Skip to content

Commit a9ac963

Browse files
committed
Add isPartial to GraphDatum
1 parent afc93e4 commit a9ac963

2 files changed

Lines changed: 113 additions & 9 deletions

File tree

assets/js/dashboard/stats-query.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type QueryInclude = {
1515
imports: boolean
1616
imports_meta: boolean
1717
time_labels: boolean
18+
partial_time_labels: boolean
1819
compare: IncludeCompare
1920
compare_match_day_of_week: boolean
2021
present_index?: boolean
@@ -49,6 +50,7 @@ export function createStatsQuery(
4950
imports: dashboardState.with_imported,
5051
imports_meta: reportParams.include?.imports_meta || false,
5152
time_labels: reportParams.include?.time_labels || false,
53+
partial_time_labels: reportParams.include?.partial_time_labels || false,
5254
compare: createIncludeCompare(dashboardState),
5355
compare_match_day_of_week: dashboardState.match_day_of_week
5456
}

assets/js/dashboard/stats/graph/main-graph.tsx

Lines changed: 111 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type MainGraphResponse = {
4141
(ResultItem & { change: [number | null] | null }) | null
4242
>
4343
meta: {
44+
partial_time_labels: string[] | null
4445
time_labels: string[]
4546
time_label_result_indices: (number | null)[]
4647
comparison_time_labels?: string[]
@@ -56,6 +57,7 @@ type MainGraphResponse = {
5657
}
5758
type GraphDatum = {
5859
value: number | null
60+
isPartial: boolean | null
5961
timeLabel: string | null
6062
comparisonValue?: number | null
6163
comparisonTimeLabel?: string | null
@@ -149,7 +151,9 @@ export const MainGraph = ({
149151
? getXLabel(datum.timeLabel, {
150152
shouldShowYear: hasMultipleYears,
151153
period,
152-
interval
154+
interval,
155+
bucketIndex: bucketIndex.valueOf(),
156+
totalBuckets: remappedData.length
153157
})
154158
: ''
155159
: ''
@@ -354,6 +358,8 @@ export const MainGraph = ({
354358
x={tooltip.x}
355359
y={tooltip.y}
356360
datum={remappedData[selectedIndex]}
361+
bucketIndex={selectedIndex}
362+
totalBuckets={remappedData.length}
357363
/>
358364
)}
359365
</div>
@@ -369,7 +375,9 @@ const GraphTooltip = ({
369375
x,
370376
y,
371377
datum,
372-
showZoomToPeriod
378+
showZoomToPeriod,
379+
bucketIndex,
380+
totalBuckets
373381
}: {
374382
metric: FormattableMetric
375383
interval: string
@@ -379,6 +387,8 @@ const GraphTooltip = ({
379387
y: number
380388
datum: GraphDatum
381389
showZoomToPeriod?: boolean
390+
bucketIndex: number
391+
totalBuckets: number
382392
width: number
383393
}) => {
384394
const formatter = MetricFormatterShort[metric]
@@ -420,10 +430,13 @@ const GraphTooltip = ({
420430
<span className="flex items-center mr-4">
421431
<div className="size-2 mr-2 rounded-full bg-indigo-400"></div>
422432
<span>
423-
{getXLabel(datum.timeLabel, {
433+
{getFullBucketLabel(datum.timeLabel, {
424434
period,
425435
interval,
426-
shouldShowYear
436+
shouldShowYear,
437+
bucketIndex,
438+
totalBuckets,
439+
isPartial: datum.isPartial!
427440
})}
428441
</span>
429442
</span>
@@ -436,10 +449,13 @@ const GraphTooltip = ({
436449
<span className="flex items-center mr-4">
437450
<div className="size-2 mr-2 rounded-full bg-gray-500"></div>
438451
<span>
439-
{getXLabel(datum.comparisonTimeLabel, {
452+
{getFullBucketLabel(datum.comparisonTimeLabel, {
440453
period,
441454
interval,
442-
shouldShowYear
455+
shouldShowYear,
456+
bucketIndex,
457+
totalBuckets,
458+
isPartial: false
443459
})}
444460
</span>
445461
</span>
@@ -480,12 +496,16 @@ const getXLabel = (
480496
{
481497
shouldShowYear,
482498
period,
483-
interval
499+
interval,
500+
bucketIndex,
501+
totalBuckets
484502
}: {
485503
shouldShowYear: boolean
486504
/* "month" | "week" | "day" | "hour" | "minute" */
487505
interval: string
488506
period: DashboardPeriod
507+
bucketIndex: number
508+
totalBuckets: number
489509
}
490510
) => {
491511
const parsedDate = parseNaiveDate(xValue)
@@ -507,7 +527,76 @@ const getXLabel = (
507527
return `${formatDayShort(parsedDate, shouldShowYear)}, ${time}`
508528
}
509529
case 'minute':
510-
if (period === 'realtime') return `${xValue}m`
530+
if (period === DashboardPeriod.realtime) {
531+
const minutesAgo = totalBuckets - bucketIndex
532+
return `-${minutesAgo}m`
533+
}
534+
return formatTime(parsedDate, {
535+
use12HourClock: is12HourClock(),
536+
includeMinutes: true
537+
})
538+
default:
539+
return ''
540+
}
541+
}
542+
543+
const getFullBucketLabel = (
544+
// in the format "YYYY-MM-DD" or "YYYY-MM-DD HH:MM:SS"
545+
xValue: string,
546+
{
547+
shouldShowYear,
548+
period,
549+
interval,
550+
bucketIndex,
551+
totalBuckets,
552+
isPartial
553+
}: {
554+
isPartial: boolean
555+
shouldShowYear: boolean
556+
/* "month" | "week" | "day" | "hour" | "minute" */
557+
interval: string
558+
period: DashboardPeriod
559+
bucketIndex: number
560+
totalBuckets: number
561+
}
562+
) => {
563+
const parsedDate = parseNaiveDate(xValue)
564+
switch (interval) {
565+
case 'month': {
566+
const month = getXLabel(xValue, {
567+
shouldShowYear,
568+
interval,
569+
period,
570+
bucketIndex,
571+
totalBuckets
572+
})
573+
return isPartial ? `Partial of ${month}` : month
574+
}
575+
case 'week': {
576+
const date = getXLabel(xValue, {
577+
shouldShowYear,
578+
interval,
579+
period,
580+
bucketIndex,
581+
totalBuckets
582+
})
583+
return isPartial ? `Partial week of ${date}` : `Week of ${date}`
584+
}
585+
case 'day':
586+
return parsedDate.format('ddd, D MMM')
587+
case 'hour':
588+
return getXLabel(xValue, {
589+
shouldShowYear,
590+
interval,
591+
period,
592+
bucketIndex,
593+
totalBuckets
594+
})
595+
case 'minute':
596+
if (period === DashboardPeriod.realtime) {
597+
const minutesAgo = totalBuckets - bucketIndex
598+
return minutesAgo === 1 ? `1 minute ago` : `${minutesAgo} minutes ago`
599+
}
511600
return formatTime(parsedDate, {
512601
use12HourClock: is12HourClock(),
513602
includeMinutes: true
@@ -558,8 +647,14 @@ const remapToGraphData = (
558647
const mainResultDefined = typeof timeLabel === 'string'
559648
const comparisonResultDefined = typeof comparisonTimeLabel === 'string'
560649

650+
let isPartial: boolean | null = null
561651
let value: number | null = null
562652
if (mainResultDefined) {
653+
isPartial = (data.meta.partial_time_labels ?? []).find(
654+
(l) => l === timeLabel
655+
)
656+
? true
657+
: false
563658
if (firstTimeLabel === null) {
564659
firstTimeLabel = timeLabel
565660
}
@@ -608,7 +703,14 @@ const remapToGraphData = (
608703
yMax = comparisonValue
609704
}
610705

611-
return { value, comparisonValue, timeLabel, comparisonTimeLabel, change }
706+
return {
707+
value,
708+
comparisonValue,
709+
timeLabel,
710+
comparisonTimeLabel,
711+
change,
712+
isPartial
713+
}
612714
})
613715

614716
const hasMultipleYears =

0 commit comments

Comments
 (0)