feat(chart): 用量详情页显示服务标识;图例只显示当前时间范围内模型(含 tooltip 残留修复)
This commit is contained in:
parent
eecf54986f
commit
a079a0bfcb
@ -551,7 +551,8 @@ internal fun StackedBarChart(
|
||||
Text(stringResource(R.string.common_no_data), color = InkMuted, style = MaterialTheme.typography.bodySmall)
|
||||
return
|
||||
}
|
||||
var tooltipBucket by remember { mutableStateOf(buckets.lastOrNull()) }
|
||||
// key = buckets:切换时间范围/筛选后重置 tooltip,避免残留旧数据
|
||||
var tooltipBucket by remember(buckets) { mutableStateOf(buckets.lastOrNull()) }
|
||||
val density = LocalDensity.current
|
||||
val d = density.density
|
||||
val barCount = buckets.size
|
||||
@ -681,7 +682,8 @@ internal fun LineChart(
|
||||
Text(stringResource(R.string.common_no_data), color = InkMuted, style = MaterialTheme.typography.bodySmall)
|
||||
return
|
||||
}
|
||||
var tooltipBucket by remember { mutableStateOf(buckets.lastOrNull()) }
|
||||
// key = buckets:切换时间范围/筛选后重置 tooltip,避免残留旧数据
|
||||
var tooltipBucket by remember(buckets) { mutableStateOf(buckets.lastOrNull()) }
|
||||
val density = LocalDensity.current
|
||||
val d = density.density
|
||||
val barCount = buckets.size
|
||||
|
||||
@ -153,10 +153,14 @@ class UsageChartViewModel @Inject constructor(
|
||||
// 降级后或用户手动选择 → 关闭降级,正常显示
|
||||
allowFallback = false
|
||||
|
||||
// 图例数据源:只保留当前显示范围内实际出现过的模型
|
||||
val rangeModels = result.flatMap { it.byModel.keys }.distinct().sorted()
|
||||
|
||||
_state.update {
|
||||
it.copy(
|
||||
buckets = result,
|
||||
allModels = allModels,
|
||||
rangeModels = rangeModels,
|
||||
loading = false
|
||||
)
|
||||
}
|
||||
@ -262,6 +266,8 @@ data class ChartUiState(
|
||||
val loading: Boolean = true,
|
||||
val granularity: ChartGranularity = ChartGranularity.LAST_5H_HOURLY,
|
||||
val allModels: List<String> = emptyList(),
|
||||
/** 当前显示范围内实际出现过的模型(图例只显示这些) */
|
||||
val rangeModels: List<String> = emptyList(),
|
||||
val selectedModels: Set<String> = emptySet(), // empty = all
|
||||
val buckets: List<ChartBucket> = emptyList(),
|
||||
val useUtc8: Boolean = false,
|
||||
|
||||
@ -53,6 +53,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
@ -110,7 +111,23 @@ fun UsageDetailScreen(
|
||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.title_usage_detail)) },
|
||||
title = {
|
||||
val serviceLabel = if (clearViewModel == null) "OCGO" else "CommandCode"
|
||||
Column {
|
||||
Text(
|
||||
stringResource(R.string.title_usage_detail),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
serviceLabel,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = InkMuted,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
},
|
||||
navigationIcon = { IconButton(onClick = onBack) { Icon(Icons.Filled.ArrowBack, stringResource(R.string.action_back)) } },
|
||||
actions = {
|
||||
if (clearViewModel != null) {
|
||||
@ -209,7 +226,7 @@ fun UsageDetailScreen(
|
||||
if (wideEnough) {
|
||||
// 面板够宽:前两张图表并排
|
||||
item {
|
||||
val models = state.selectedModels.ifEmpty { state.allModels.toSet() }
|
||||
val models = state.rangeModels
|
||||
val costTotal = state.buckets.sumOf { it.totalCost.toDouble() / 100_000_000.0 }
|
||||
val reqTotal = state.buckets.sumOf { it.totalRequests }
|
||||
Row(
|
||||
@ -256,7 +273,7 @@ fun UsageDetailScreen(
|
||||
} else {
|
||||
// 窄面板:三张图表纵向堆叠
|
||||
item {
|
||||
val models = state.selectedModels.ifEmpty { state.allModels.toSet() }
|
||||
val models = state.rangeModels
|
||||
val costTotal = state.buckets.sumOf { it.totalCost.toDouble() / 100_000_000.0 }
|
||||
ChartCard(stringResource(R.string.chart_cost), "$${String.format(Locale.US, "%.4f", costTotal)}", { showCostDetail = true }) {
|
||||
StackedBarChart(state.buckets,
|
||||
@ -331,7 +348,7 @@ fun UsageDetailScreen(
|
||||
minDate = startDate
|
||||
)
|
||||
}
|
||||
val models = state.selectedModels.ifEmpty { state.allModels.toSet() }
|
||||
val models = state.rangeModels
|
||||
if (showCostDetail) ChartDetailDialog(stringResource(R.string.chart_detail_cost), { showCostDetail = false }) {
|
||||
models.forEach { model -> val t = state.buckets.sumOf { it.byModel[model]?.cost ?:0L }; if (t>0) DetailRow(model, "$${String.format(Locale.US, "%.4f", t/100_000_000.0)}") }
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user