From 32b40371a31b3984e01f5a072e8e9c7a1e6acc2b Mon Sep 17 00:00:00 2001 From: cloudroam <cloudroam> Date: 星期三, 12 三月 2025 17:00:38 +0800 Subject: [PATCH] fix: 1 --- app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt | 209 +++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 148 insertions(+), 61 deletions(-) diff --git a/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt b/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt index cecb616..967a83c 100644 --- a/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt +++ b/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt @@ -23,6 +23,7 @@ import android.graphics.Color import android.widget.GridLayout import com.example.firstapp.model.DailyStat +import com.github.mikephil.charting.components.YAxis class DashboardFragment : Fragment() { @@ -162,23 +163,20 @@ position = XAxis.XAxisPosition.BOTTOM setDrawGridLines(false) granularity = 1f - labelRotationAngle = -45f - textSize = 10f + labelRotationAngle = 0f + textSize = 10f //标签字体 + setExtraLeftOffset(5f) // 减少左侧留白 + setExtraBottomOffset(15f) } // Y轴设置 axisLeft.apply { setDrawGridLines(true) axisMinimum = 0f - granularity = 0.5f // 将刻度间隔设为0.5 + granularity = 1f valueFormatter = object : ValueFormatter() { override fun getFormattedValue(value: Float): String { - // 只有整数时才显示标签 - return if (value % 1 == 0f) { - value.toInt().toString() - } else { - "" - } + return if (value > 0) value.toInt().toString() else "" } } } @@ -188,8 +186,13 @@ setTouchEnabled(true) isDragEnabled = true setScaleEnabled(true) + + // 设置边距 + setExtraOffsets(10f, 10f, 10f, 20f) } + + updateBarChartData() } private fun updateBarChartData() { @@ -207,7 +210,11 @@ if (stats.isEmpty()) return@observe val entries = stats.mapIndexed { index, stat -> - BarEntry(index.toFloat(), stat.count.toFloat()) + val entry = BarEntry(index.toFloat(), stat.count.toFloat()) + if (stat.count == 0) { + entry.data = "hide_label" + } + entry } val dataSet = BarDataSet(entries, "包裹数量") @@ -216,7 +223,7 @@ valueTextSize = 12f valueFormatter = object : ValueFormatter() { override fun getFormattedValue(value: Float): String { - return value.toInt().toString() + return if (value > 0) value.toInt().toString() else "" } } } @@ -233,13 +240,27 @@ return when(currentDateType) { DateType.WEEK -> { val weekStat = stats[position] - val calendar = Calendar.getInstance() - calendar.timeInMillis = weekStat.weekStart!! - SimpleDateFormat("MM/dd", Locale.getDefault()).format(calendar.time) + try { + // 解析日期字符串 + val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) + val date = sdf.parse(weekStat.date) + val calendar = Calendar.getInstance() + calendar.time = date + + // 获取年份和周数 + val weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR) + val year = calendar.get(Calendar.YEAR) + + // 显示格式:第X周 +// "第${weekOfYear}周" + "${weekOfYear}" + } catch (e: Exception) { + weekStat.date + } } +// DateType.MONTH -> "${stats[position].date}月" DateType.MONTH -> { - // 显示月份标签(1-12月) - "${position + 1}月" + stats[position].date.replaceFirst("^0+".toRegex(), "") } else -> "" } @@ -247,15 +268,16 @@ return "" } } - position = XAxis.XAxisPosition.BOTTOM - setDrawGridLines(false) labelCount = stats.size - granularity = 1f - labelRotationAngle = -45f - textSize = 10f + setAvoidFirstLastClipping(true) + labelRotationAngle = 0f + + // 增加标签间距 +// setExtraBottomOffset(20f) + textSize = 11f // 稍微调小字体 } - // 高亮当前月份 + // 高亮显示 if (currentDateType == DateType.MONTH) { val currentMonth = currentDate.get(Calendar.MONTH) dataSet.setColors(List(stats.size) { index -> @@ -263,42 +285,50 @@ else resources.getColor(R.color.purple_200) }) } else if (currentDateType == DateType.WEEK) { - // 保持周视图的高亮逻辑 - val highlightIndex = 3f + val highlightIndex = 3 // 当前周在第4个位置 dataSet.setColors(List(stats.size) { index -> - if (index == 3) resources.getColor(R.color.purple_500) + if (index == highlightIndex) resources.getColor(R.color.purple_500) else resources.getColor(R.color.purple_200) }) } + // 刷新图表 + barChart.notifyDataSetChanged() barChart.invalidate() } } private fun setupPieChart() { pieChart.apply { + // 隐藏图表描述(右下角默认文字) description.isEnabled = false + // 显示实际值而非百分比 setUsePercentValues(false) + // 隐藏饼图区块上的标签(如数值或名称) setDrawEntryLabels(false) - - // 调整饼图边距 - setExtraOffsets(20f, 10f, 60f, 10f) - + + // 设置饼图与容器的边距,参数顺序:左、上、右、下 + // 右侧留出 80f 空间,可能为图例腾出位置 + setExtraOffsets(20f, 20f, 20f, 20f) + + + // 配置图例 legend.apply { - isEnabled = true - verticalAlignment = Legend.LegendVerticalAlignment.CENTER - horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT - orientation = Legend.LegendOrientation.VERTICAL - setDrawInside(false) - xEntrySpace = 10f - yEntrySpace = 5f - yOffset = 0f - textSize = 14f + isEnabled = true // 启用图例 + verticalAlignment = Legend.LegendVerticalAlignment.CENTER // 垂直居中 + horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT // 水平靠右对齐 + orientation = Legend.LegendOrientation.VERTICAL // 图例项垂直排列 + setDrawInside(false) // 图例绘制在图表外部(而非覆盖在图上) + xEntrySpace = 10f // 图例项水平间距 + yEntrySpace = 5f // 图例项垂直间距 + yOffset = 0f // 图例整体 Y 轴无偏移 + textSize = 12f // 图例文字大小 } - // 设置中心空白 - holeRadius = 45f - transparentCircleRadius = 50f + // 调整中心空白区域大小 + holeRadius = 20f // 中间空心圆的半径(占饼图比例) + transparentCircleRadius = 25f // 透明圆圈的半径(可能用于边框效果) + } updatePieChartData() @@ -341,8 +371,38 @@ currentDate.timeInMillis, currentDateType.name ).observe(viewLifecycleOwner) { packages -> + when (currentDateType) { + DateType.DAY -> { + binding.textPackageCount.text = "${packages.size}个" + } + DateType.WEEK -> { + // 获取本周统计 + viewModel.getCurrentWeekStats(currentDate.timeInMillis) + .observe(viewLifecycleOwner) { stats -> + val weekTotal = stats.sumOf { it.count } + binding.textPackageCount.text = "${weekTotal}个" + } + } + DateType.MONTH -> { + // 获取本月统计 + viewModel.getMonthlyStats(currentDate.timeInMillis) + .observe(viewLifecycleOwner) { stats -> + val monthTotal = stats.sumOf { it.count } + binding.textPackageCount.text = "${monthTotal}个" + } + } + DateType.YEAR -> { + // 获取本年统计 + viewModel.getCurrentYearStats(currentDate.timeInMillis) + .observe(viewLifecycleOwner) { stats -> + val yearTotal = stats.sumOf { it.count } + binding.textPackageCount.text = "${yearTotal}个" + } + } + } packageAdapter.updatePackages(packages) - binding.textPackageCount.text = "${packages.size}个" + packageAdapter.updatePackages(packages) +// binding.textPackageCount.text = "${packages.size}个" } } private fun setupHeatmap() { @@ -367,24 +427,44 @@ // 更新UI binding.layoutWeekStats.heatmapYearly.apply { - // 清除现有的子视图 removeAllViews() - // 创建网格布局 val gridLayout = GridLayout(context).apply { - rowCount = 7 - columnCount = 52 + rowCount = 8 // 增加一行用于显示月份 + columnCount = 53 // 增加一列用于显示星期标签 } - // 添加日期标签 - val dayLabels = arrayOf("周日", "周一", "周二", "周三", "周四", "周五", "周六") - for (i in 0..6) { + // 添加月份标签 + val months = arrayOf("1月", "2月", "3月", "4月", "5月", "6月", + "7月", "8月", "9月", "10月", "11月", "12月") + months.forEachIndexed { index, month -> val label = TextView(context).apply { - text = dayLabels[i] + text = month textSize = 10f - setPadding(0, 0, 8, 0) + setPadding(0, 0, 8, 4) + // 计算每个月份标签的位置 + val weekPosition = (index * 4.3).toInt() + val params = GridLayout.LayoutParams() + params.columnSpec = GridLayout.spec(weekPosition + 1) + params.rowSpec = GridLayout.spec(0) + layoutParams = params } gridLayout.addView(label) + } + + // 添加星期标签 + val dayLabels = arrayOf("周一", "周二", "周三", "周四", "周五", "周六", "周日") + dayLabels.forEachIndexed { index, label -> + val textView = TextView(context).apply { + text = label + textSize = 10f + setPadding(4, 0, 8, 0) + val params = GridLayout.LayoutParams() + params.columnSpec = GridLayout.spec(0) + params.rowSpec = GridLayout.spec(index + 1) + layoutParams = params + } + gridLayout.addView(textView) } // 添加热力图单元格 @@ -392,12 +472,15 @@ for (week in 0..51) { val count = heatmapMatrix[day][week] val cell = View(context).apply { - layoutParams = ViewGroup.LayoutParams( - resources.getDimensionPixelSize(R.dimen.heatmap_cell_size), - resources.getDimensionPixelSize(R.dimen.heatmap_cell_size) - ) + val params = GridLayout.LayoutParams().apply { + width = resources.getDimensionPixelSize(R.dimen.heatmap_cell_size) + height = resources.getDimensionPixelSize(R.dimen.heatmap_cell_size) + columnSpec = GridLayout.spec(week + 1) + rowSpec = GridLayout.spec(day + 1) + setMargins(1, 1, 1, 1) + } + layoutParams = params setBackgroundColor(getHeatmapColor(count)) - setPadding(1, 1, 1, 1) } gridLayout.addView(cell) } @@ -409,12 +492,11 @@ } private fun getHeatmapColor(count: Int): Int { - // 根据数量返回不同深浅的颜色 return when { count == 0 -> Color.parseColor("#EBEDF0") - count <= 2 -> Color.parseColor("#9BE9A8") - count <= 4 -> Color.parseColor("#40C463") - count <= 6 -> Color.parseColor("#30A14E") + count == 1 -> Color.parseColor("#9BE9A8") + count == 2 -> Color.parseColor("#40C463") + count <= 4 -> Color.parseColor("#30A14E") else -> Color.parseColor("#216E39") } } @@ -426,6 +508,7 @@ binding.recyclerPackages.visibility = View.VISIBLE binding.layoutWeekStats.root.visibility = View.GONE binding.layoutYearStats.root.visibility = View.GONE + binding.cardPackageStats.visibility = View.VISIBLE } DateType.WEEK, DateType.MONTH -> { // 周和月视图显示柱状图和饼图,隐藏包裹列表 @@ -433,7 +516,9 @@ binding.layoutWeekStats.root.visibility = View.VISIBLE binding.layoutYearStats.root.visibility = View.GONE binding.layoutWeekStats.chartDailyPackages.visibility = View.VISIBLE + (binding.layoutWeekStats.chartDailyPackages.parent as? View)?.visibility = View.VISIBLE binding.layoutWeekStats.heatmapYearly.visibility = View.GONE + binding.cardPackageStats.visibility = View.VISIBLE updateBarChartData() updatePieChartData() } @@ -442,10 +527,12 @@ binding.recyclerPackages.visibility = View.GONE binding.layoutWeekStats.root.visibility = View.VISIBLE binding.layoutYearStats.root.visibility = View.VISIBLE - binding.layoutWeekStats.chartDailyPackages.visibility = View.GONE + (binding.layoutWeekStats.chartDailyPackages.parent as? View)?.visibility = View.GONE binding.layoutWeekStats.heatmapYearly.visibility = View.VISIBLE + binding.cardPackageStats.visibility = View.GONE updateHeatmapData() updatePieChartData() + updateYearlyStats() } } } -- Gitblit v1.9.3