SYNC: chart - support group by week

This commit is contained in:
SPRINX0\prochazka
2025-09-26 16:51:03 +02:00
committed by Diflow
parent 6a6633e151
commit bcbd96c608
3 changed files with 62 additions and 10 deletions

View File

@@ -4,6 +4,7 @@ export type ChartXTransformFunction =
| 'date:minute' | 'date:minute'
| 'date:hour' | 'date:hour'
| 'date:day' | 'date:day'
| 'date:week'
| 'date:month' | 'date:month'
| 'date:year'; | 'date:year';
export type ChartYAggregateFunction = 'sum' | 'first' | 'last' | 'min' | 'max' | 'count' | 'avg'; export type ChartYAggregateFunction = 'sum' | 'first' | 'last' | 'min' | 'max' | 'count' | 'avg';
@@ -70,6 +71,7 @@ export interface ChartDateParsed {
minute?: number; minute?: number;
second?: number; second?: number;
fraction?: string; fraction?: string;
week?: number;
} }
export interface ChartAvailableColumn { export interface ChartAvailableColumn {

View File

@@ -9,7 +9,7 @@ import {
ChartYFieldDefinition, ChartYFieldDefinition,
ProcessedChart, ProcessedChart,
} from './chartDefinitions'; } 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) { export function getChartDebugPrint(chart: ProcessedChart) {
let res = ''; let res = '';
@@ -29,6 +29,7 @@ export function tryParseChartDate(dateInput: any): ChartDateParsed | null {
return { return {
year: dateInput.getFullYear(), year: dateInput.getFullYear(),
month: dateInput.getMonth() + 1, month: dateInput.getMonth() + 1,
week: getWeek(dateInput),
day: dateInput.getDate(), day: dateInput.getDate(),
hour: dateInput.getHours(), hour: dateInput.getHours(),
minute: dateInput.getMinutes(), 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})?)?$/ /^(\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 monthMatch = dateInput.match(/^(\d{4})-(\d{2})$/);
const weekMatch = dateInput.match(/^(\d{4})\@(\d{2})$/);
// const yearMatch = dateInput.match(/^(\d{4})$/); // const yearMatch = dateInput.match(/^(\d{4})$/);
if (dateMatch) { 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 { return {
year: parseInt(year, 10), year,
month: parseInt(month, 10), month,
day: parseInt(day, 10), week: getWeek(new Date(year, month - 1, day)),
day,
hour: parseInt(hour, 10) || 0, hour: parseInt(hour, 10) || 0,
minute: parseInt(minute, 10) || 0, minute: parseInt(minute, 10) || 0,
second: parseInt(second, 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) { // if (yearMatch) {
// const [_notUsed, year] = yearMatch; // const [_notUsed, year] = yearMatch;
// return { // return {
@@ -97,6 +117,8 @@ export function stringifyChartDate(value: ChartDateParsed, transform: ChartXTran
return `${value.year}`; return `${value.year}`;
case 'date:month': case 'date:month':
return `${value.year}-${pad2Digits(value.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': case 'date:day':
return `${value.year}-${pad2Digits(value.month)}-${pad2Digits(value.day)}`; return `${value.year}-${pad2Digits(value.month)}-${pad2Digits(value.day)}`;
case 'date:hour': case 'date:hour':
@@ -126,6 +148,9 @@ export function incrementChartDate(value: ChartDateParsed, transform: ChartXTran
case 'date:month': case 'date:month':
newDateRepresentation = addMonths(dateRepresentation, 1); newDateRepresentation = addMonths(dateRepresentation, 1);
break; break;
case 'date:week':
newDateRepresentation = addWeeks(dateRepresentation, 1);
break;
case 'date:day': case 'date:day':
newDateRepresentation = addDays(dateRepresentation, 1); newDateRepresentation = addDays(dateRepresentation, 1);
break; break;
@@ -144,6 +169,11 @@ export function incrementChartDate(value: ChartDateParsed, transform: ChartXTran
year: newDateRepresentation.getFullYear(), year: newDateRepresentation.getFullYear(),
month: newDateRepresentation.getMonth() + 1, month: newDateRepresentation.getMonth() + 1,
}; };
case 'date:week':
return {
year: newDateRepresentation.getFullYear(),
week: getWeek(newDateRepresentation),
};
case 'date:day': case 'date:day':
return { return {
year: newDateRepresentation.getFullYear(), year: newDateRepresentation.getFullYear(),
@@ -175,6 +205,8 @@ export function runTransformFunction(value: string, transformFunction: ChartXTra
return dateParsed ? `${dateParsed.year}` : null; return dateParsed ? `${dateParsed.year}` : null;
case 'date:month': case 'date:month':
return dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}` : null; return dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}` : null;
case 'date:week':
return dateParsed ? `${dateParsed.year}@${pad2Digits(dateParsed.week)}` : null;
case 'date:day': case 'date:day':
return dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)}` : null; return dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)}` : null;
case 'date:hour': case 'date:hour':
@@ -211,6 +243,14 @@ export function computeChartBucketKey(
month: dateParsed.month, month: dateParsed.month,
}, },
]; ];
case 'date:week':
return [
dateParsed ? `${dateParsed.year}@${pad2Digits(dateParsed.week)}` : null,
{
year: dateParsed.year,
week: dateParsed.week,
},
];
case 'date:day': case 'date:day':
return [ return [
dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)}` : null, dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)}` : null,
@@ -265,6 +305,8 @@ export function computeDateBucketDistance(
return end.year - begin.year; return end.year - begin.year;
case 'date:month': case 'date:month':
return (end.year - begin.year) * 12 + (end.month - begin.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': case 'date:day':
return ( return (
(end.year - begin.year) * 365 + (end.year - begin.year) * 365 +
@@ -302,6 +344,8 @@ export function compareChartDatesParsed(
return a.year - b.year; return a.year - b.year;
case 'date:month': case 'date:month':
return a.year === b.year ? a.month - b.month : a.year - b.year; 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': case 'date:day':
return a.year === b.year && a.month === b.month return a.year === b.year && a.month === b.month
? a.day - b.day ? a.day - b.day
@@ -356,6 +400,8 @@ function getParentDateBucketKey(
return null; // no parent for year return null; // no parent for year
case 'date:month': case 'date:month':
return bucketKey.slice(0, 4); return bucketKey.slice(0, 4);
case 'date:week':
return bucketKey.slice(0, 4);
case 'date:day': case 'date:day':
return bucketKey.slice(0, 7); return bucketKey.slice(0, 7);
case 'date:hour': case 'date:hour':
@@ -371,6 +417,8 @@ function getParentDateBucketTransform(transform: ChartXTransformFunction): Chart
return null; // no parent for year return null; // no parent for year
case 'date:month': case 'date:month':
return 'date:year'; return 'date:year';
case 'date:week':
return 'date:year';
case 'date:day': case 'date:day':
return 'date:month'; return 'date:month';
case 'date:hour': case 'date:hour':
@@ -388,6 +436,8 @@ function getParentKeyParsed(date: ChartDateParsed, transform: ChartXTransformFun
return null; // no parent for year return null; // no parent for year
case 'date:month': case 'date:month':
return { year: date.year }; return { year: date.year };
case 'date:week':
return { year: date.week };
case 'date:day': case 'date:day':
return { year: date.year, month: date.month }; return { year: date.year, month: date.month };
case 'date:hour': case 'date:hour':

View File

@@ -5113,6 +5113,11 @@ bluebird@^3.7.2:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== 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: body-parser@1.20.2, body-parser@^1.19.0:
version "1.20.2" version "1.20.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" 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" pacote "^11.1.13"
rimraf "^3.0.2" 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: dbgate-query-splitter@^4.11.7:
version "4.11.7" version "4.11.7"
resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.7.tgz#f9d53b3ceafbd76355152677b87ae453598b4a88" resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.7.tgz#f9d53b3ceafbd76355152677b87ae453598b4a88"