mirror of
https://github.com/modrinth/code.git
synced 2026-07-31 13:16:38 +00:00
feat: dont show analytics incomplete current day revenue
This commit is contained in:
+7
@@ -27,6 +27,7 @@ import {
|
||||
LineController,
|
||||
LineElement,
|
||||
PointElement,
|
||||
type ScriptableLineSegmentContext,
|
||||
Tooltip,
|
||||
} from 'chart.js'
|
||||
|
||||
@@ -446,6 +447,12 @@ function buildDatasets() {
|
||||
pointHoverBackgroundColor: colors.borderColor,
|
||||
pointHoverBorderWidth: 0,
|
||||
pointHitRadius: 16,
|
||||
segment: dataset.lastDataPointUnavailable
|
||||
? {
|
||||
borderColor: (context: ScriptableLineSegmentContext) =>
|
||||
context.p1DataIndex === dataset.data.length - 1 ? 'transparent' : undefined,
|
||||
}
|
||||
: undefined,
|
||||
stack: props.stacked ? 'analytics' : undefined,
|
||||
}
|
||||
})
|
||||
|
||||
+10
-2
@@ -59,7 +59,9 @@
|
||||
<span class="font-medium text-primary">
|
||||
{{ formatMessage(analyticsChartMessages.total) }}
|
||||
</span>
|
||||
<span class="font-semibold text-contrast">{{ formattedTotal }}</span>
|
||||
<span class="font-semibold" :class="totalHasData ? 'text-contrast' : 'text-primary'">
|
||||
{{ formattedTotal }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-for="entry in entries"
|
||||
@@ -111,7 +113,11 @@
|
||||
:class="[
|
||||
'shrink-0',
|
||||
entry.isPreviousPeriod ? 'font-medium text-secondary' : 'font-semibold',
|
||||
entry.hidden ? 'text-primary line-through opacity-70' : 'text-contrast',
|
||||
entry.hidden
|
||||
? 'text-primary line-through opacity-70'
|
||||
: entry.noData
|
||||
? 'text-primary'
|
||||
: 'text-contrast',
|
||||
]"
|
||||
>
|
||||
{{ entry.formattedValue }}
|
||||
@@ -148,6 +154,7 @@ export type AnalyticsChartTooltipEntry = {
|
||||
tooltip?: string
|
||||
color: string
|
||||
formattedValue: string
|
||||
noData: boolean
|
||||
hidden: boolean
|
||||
toggleDisabled: boolean
|
||||
isPreviousPeriod?: boolean
|
||||
@@ -164,6 +171,7 @@ const props = defineProps<{
|
||||
chartStart: Date | null
|
||||
chartEnd: Date | null
|
||||
formattedTotal: string
|
||||
totalHasData: boolean
|
||||
entries: AnalyticsChartTooltipEntry[]
|
||||
containerWidth: number
|
||||
containerHeight: number
|
||||
|
||||
+28
-3
@@ -64,6 +64,7 @@
|
||||
:chart-start="chartRangeBounds?.start ?? null"
|
||||
:chart-end="chartRangeBounds?.end ?? null"
|
||||
:formatted-total="hoverFormattedTotal"
|
||||
:total-has-data="hoverHasData"
|
||||
:entries="hoverEntries"
|
||||
:container-width="containerSize.width"
|
||||
:container-height="containerSize.height"
|
||||
@@ -89,6 +90,7 @@ import type {
|
||||
AnalyticsGroupByPreset,
|
||||
} from '~/providers/analytics/analytics'
|
||||
|
||||
import { analyticsChartMessages } from '../../analytics-messages.ts'
|
||||
import type {
|
||||
AnalyticsChartLegendEntry,
|
||||
AnalyticsChartRangeBounds,
|
||||
@@ -188,7 +190,26 @@ const hoverTotalValue = computed(() => {
|
||||
}, 0)
|
||||
})
|
||||
|
||||
function hasDatasetDataAtSlice(dataset: ChartDataset | undefined, sliceIndex: number) {
|
||||
if (!dataset) return false
|
||||
return !dataset.lastDataPointUnavailable || sliceIndex !== dataset.data.length - 1
|
||||
}
|
||||
|
||||
const hoverHasData = computed(() => {
|
||||
if (hoverState.sliceIndex === null) return false
|
||||
const sliceIndex = hoverState.sliceIndex
|
||||
|
||||
return props.currentLegendEntries.some((legendEntry) => {
|
||||
if (legendEntry.hidden) return false
|
||||
const dataset = props.chartDatasetById.get(legendEntry.id)
|
||||
return hasDatasetDataAtSlice(dataset, sliceIndex)
|
||||
})
|
||||
})
|
||||
|
||||
const hoverFormattedTotal = computed(() => {
|
||||
if (!hoverHasData.value) {
|
||||
return formatMessage(analyticsChartMessages.noData)
|
||||
}
|
||||
if (props.isRatioMode) {
|
||||
return hoverTotalValue.value > 0 ? '100%' : '0%'
|
||||
}
|
||||
@@ -203,6 +224,7 @@ const hoverEntries = computed(() => {
|
||||
return props.legendEntries.map((legendEntry) => {
|
||||
const dataset = props.chartDatasetById.get(legendEntry.id)
|
||||
const value = dataset?.data[sliceIndex] ?? 0
|
||||
const hasData = hasDatasetDataAtSlice(dataset, sliceIndex)
|
||||
const ratioValue = legendEntry.hidden || totalValue === 0 ? 0 : (value / totalValue) * 100
|
||||
return {
|
||||
projectId: legendEntry.id,
|
||||
@@ -210,9 +232,12 @@ const hoverEntries = computed(() => {
|
||||
projectName: legendEntry.projectName,
|
||||
tooltip: legendEntry.tooltip,
|
||||
color: legendEntry.color,
|
||||
formattedValue: props.isRatioMode
|
||||
? `${ratioValue.toFixed(1)}%`
|
||||
: formatMetricValue(value, props.activeStat, formatNumber, formatMessage),
|
||||
formattedValue: hasData
|
||||
? props.isRatioMode
|
||||
? `${ratioValue.toFixed(1)}%`
|
||||
: formatMetricValue(value, props.activeStat, formatNumber, formatMessage)
|
||||
: formatMessage(analyticsChartMessages.noData),
|
||||
noData: !hasData,
|
||||
hidden: legendEntry.hidden,
|
||||
toggleDisabled: !legendEntry.hidden && isLegendEntryToggleDisabled(legendEntry),
|
||||
isPreviousPeriod: legendEntry.isPreviousPeriod,
|
||||
|
||||
+1
@@ -38,6 +38,7 @@ export type ChartDataset = {
|
||||
projectName?: string
|
||||
tooltip?: string
|
||||
data: number[]
|
||||
lastDataPointUnavailable?: boolean
|
||||
borderColor: string
|
||||
backgroundColor: string
|
||||
borderDash?: number[]
|
||||
|
||||
+27
-4
@@ -32,6 +32,7 @@ import {
|
||||
type ChartDataset,
|
||||
getChartDatasetTotal,
|
||||
getShortHourlyAxisTickLimit,
|
||||
getSliceBucketRange,
|
||||
getSliceCount,
|
||||
shouldCapitalizeBreakdownLabel,
|
||||
} from './analytics-chart-utils'
|
||||
@@ -161,8 +162,8 @@ export function useAnalyticsChartDatasets(
|
||||
)
|
||||
: undefined
|
||||
})
|
||||
const chartDatasetsByStat = computed<Record<AnalyticsDashboardStat, ChartDataset[]>>(() =>
|
||||
buildDatasetsByStat(
|
||||
const chartDatasetsByStat = computed<Record<AnalyticsDashboardStat, ChartDataset[]>>(() => {
|
||||
const datasets = buildDatasetsByStat(
|
||||
context.displayedTimeSlices.value,
|
||||
selectedProjects.value,
|
||||
legendPalette.value,
|
||||
@@ -175,8 +176,20 @@ export function useAnalyticsChartDatasets(
|
||||
showProjectVersionNames.value ? context.getVersionProjectName : undefined,
|
||||
formatMessage,
|
||||
sliceCount.value,
|
||||
),
|
||||
)
|
||||
)
|
||||
const nextFetchRequest = context.displayedFetchRequest.value
|
||||
if (
|
||||
nextFetchRequest &&
|
||||
context.displayedSelectedGroupBy.value === 'day' &&
|
||||
isLastBucketCurrentDay(nextFetchRequest.time_range, sliceCount.value)
|
||||
) {
|
||||
datasets.revenue = datasets.revenue.map((dataset) => ({
|
||||
...dataset,
|
||||
lastDataPointUnavailable: true,
|
||||
}))
|
||||
}
|
||||
return datasets
|
||||
})
|
||||
const previousChartDatasetsByStat = computed<Record<AnalyticsDashboardStat, ChartDataset[]>>(() =>
|
||||
buildDatasetsByStat(
|
||||
context.displayedPreviousTimeSlices.value,
|
||||
@@ -406,6 +419,16 @@ function buildDatasetsByStat(
|
||||
return datasetsByStat
|
||||
}
|
||||
|
||||
function isLastBucketCurrentDay(timeRange: Labrinth.Analytics.v3.TimeRange, sliceCount: number) {
|
||||
const lastBucket = getSliceBucketRange(timeRange, sliceCount, sliceCount - 1)
|
||||
const todayStart = new Date()
|
||||
todayStart.setHours(0, 0, 0, 0)
|
||||
const tomorrowStart = new Date(todayStart)
|
||||
tomorrowStart.setDate(tomorrowStart.getDate() + 1)
|
||||
|
||||
return lastBucket.start < tomorrowStart && lastBucket.end > todayStart
|
||||
}
|
||||
|
||||
function sortDatasetsByTotal(datasets: ChartDataset[]) {
|
||||
return [...datasets]
|
||||
.sort((a, b) => {
|
||||
|
||||
@@ -688,6 +688,10 @@ export const analyticsChartMessages = defineMessages({
|
||||
id: 'analytics.chart.tooltip.hide-entry',
|
||||
defaultMessage: 'Hide {name} in graph',
|
||||
},
|
||||
noData: {
|
||||
id: 'analytics.chart.tooltip.no-data',
|
||||
defaultMessage: 'No data',
|
||||
},
|
||||
durationDays: {
|
||||
id: 'analytics.chart.tooltip.duration.days',
|
||||
defaultMessage: '{count, plural, one {# day} other {# days}}',
|
||||
|
||||
@@ -191,6 +191,9 @@
|
||||
"analytics.chart.tooltip.hide-entry": {
|
||||
"message": "Hide {name} in graph"
|
||||
},
|
||||
"analytics.chart.tooltip.no-data": {
|
||||
"message": "No data"
|
||||
},
|
||||
"analytics.chart.tooltip.pinned": {
|
||||
"message": "Chart tooltip pinned"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user