| | |
| | | import com.github.mikephil.charting.components.XAxis |
| | | import com.github.mikephil.charting.data.* |
| | | import com.github.mikephil.charting.formatter.IndexAxisValueFormatter |
| | | import com.github.mikephil.charting.formatter.ValueFormatter |
| | | import java.util.* |
| | | import java.text.SimpleDateFormat |
| | | import android.util.Log |
| | | |
| | | class DashboardFragment : Fragment() { |
| | | |
| | |
| | | setupPieChart() |
| | | } |
| | | private fun setupBarChart() { |
| | | // 配置柱状图 |
| | | barChart.apply { |
| | | description.isEnabled = false |
| | | setDrawGridBackground(false) |
| | | legend.isEnabled = false |
| | | |
| | | // 增大图表高度 |
| | | minimumHeight = (resources.displayMetrics.density * 300).toInt() |
| | | |
| | | // X轴设置 |
| | | xAxis.apply { |
| | | position = XAxis.XAxisPosition.BOTTOM |
| | | setDrawGridLines(false) |
| | | valueFormatter = IndexAxisValueFormatter(getDayLabels()) |
| | | granularity = 1f |
| | | labelRotationAngle = -45f |
| | | textSize = 10f |
| | | } |
| | | |
| | | // Y轴设置 |
| | | axisLeft.apply { |
| | | setDrawGridLines(true) |
| | | axisMinimum = 0f |
| | | granularity = 1f |
| | | valueFormatter = object : ValueFormatter() { |
| | | override fun getFormattedValue(value: Float): String { |
| | | return value.toInt().toString() |
| | | } |
| | | } |
| | | } |
| | | axisRight.isEnabled = false |
| | | |
| | | // 设置图表交互 |
| | | setTouchEnabled(true) |
| | | isDragEnabled = true |
| | | setScaleEnabled(true) |
| | | } |
| | | |
| | | updateBarChartData() |
| | | } |
| | | private fun updateBarChartData() { |
| | | viewModel.getDailyStats(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats -> |
| | | viewModel.getDailyStats().observe(viewLifecycleOwner) { stats -> |
| | | // 添加调试日志 |
| | | Log.d("DashboardFragment", "Stats size: ${stats.size}") |
| | | stats.forEach { stat -> |
| | | Log.d("DashboardFragment", "Week: ${stat.date}, Count: ${stat.count}, Start: ${stat.week_start}") |
| | | } |
| | | |
| | | if (stats.isEmpty()) { |
| | | Log.d("DashboardFragment", "No data found") |
| | | return@observe |
| | | } |
| | | |
| | | val entries = stats.mapIndexed { index, stat -> |
| | | BarEntry(index.toFloat(), stat.count.toFloat()) |
| | | } |
| | | |
| | | val dataSet = BarDataSet(entries, "包裹数量") |
| | | dataSet.color = resources.getColor(R.color.purple_500) |
| | | dataSet.valueTextSize = 12f |
| | | |
| | | barChart.data = BarData(dataSet) |
| | | val barData = BarData(dataSet) |
| | | barChart.data = barData |
| | | |
| | | // 设置X轴标签 |
| | | barChart.xAxis.apply { |
| | | valueFormatter = object : ValueFormatter() { |
| | | override fun getFormattedValue(value: Float): String { |
| | | val position = value.toInt() |
| | | if (position >= 0 && position < stats.size) { |
| | | val weekNum = stats[position].date.toIntOrNull() ?: 0 |
| | | // 获取月份信息 |
| | | val monthDay = stats[position].week_start?.let { |
| | | SimpleDateFormat("MM-dd", Locale.getDefault()).format( |
| | | SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).parse(it) |
| | | ) |
| | | } ?: "" |
| | | return "${monthDay}\n第${weekNum}周" |
| | | } |
| | | return "" |
| | | } |
| | | } |
| | | labelCount = stats.size |
| | | } |
| | | |
| | | barChart.notifyDataSetChanged() |
| | | barChart.invalidate() |
| | | } |
| | | } |
| | | private fun setupPieChart() { |
| | | // 配置饼图 |
| | | pieChart.apply { |
| | | description.isEnabled = false |
| | | setUsePercentValues(true) |
| | | setUsePercentValues(false) // 改为显示实际数量 |
| | | setDrawEntryLabels(false) |
| | | |
| | | legend.isEnabled = true |
| | | legend.verticalAlignment = Legend.LegendVerticalAlignment.CENTER |
| | | legend.horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT |
| | | legend.orientation = Legend.LegendOrientation.VERTICAL |
| | | // 增大饼图尺寸 |
| | | setExtraOffsets(20f, 10f, 80f, 10f) |
| | | minimumHeight = (resources.displayMetrics.density * 400).toInt() // 设置最小高度 |
| | | |
| | | // 配置图例 |
| | | legend.apply { |
| | | isEnabled = true |
| | | verticalAlignment = Legend.LegendVerticalAlignment.CENTER |
| | | horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT |
| | | orientation = Legend.LegendOrientation.VERTICAL |
| | | setDrawInside(false) |
| | | xEntrySpace = 7f |
| | | yEntrySpace = 0f |
| | | yOffset = 0f |
| | | textSize = 12f // 增大图例文字大小 |
| | | } |
| | | } |
| | | |
| | | updatePieChartData() |
| | |
| | | private fun updatePieChartData() { |
| | | viewModel.getCourierStats(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats -> |
| | | val entries = stats.map { stat -> |
| | | PieEntry(stat.count.toFloat(), stat.courierName) |
| | | PieEntry(stat.count.toFloat(), "${stat.courierName}(${stat.count})") |
| | | } |
| | | |
| | | val dataSet = PieDataSet(entries, "快递公司分布") |
| | | dataSet.colors = listOf( |
| | | resources.getColor(R.color.purple_500), |
| | | resources.getColor(R.color.teal_200) |
| | | resources.getColor(R.color.teal_200), |
| | | resources.getColor(R.color.purple_200), |
| | | resources.getColor(R.color.teal_700) |
| | | ) |
| | | dataSet.valueTextSize = 14f // 增大数值文字大小 |
| | | |
| | | pieChart.data = PieData(dataSet) |
| | | val pieData = PieData(dataSet) |
| | | pieData.setValueFormatter(object : ValueFormatter() { |
| | | override fun getFormattedValue(value: Float): String { |
| | | return value.toInt().toString() |
| | | } |
| | | }) |
| | | |
| | | pieChart.data = pieData |
| | | pieChart.invalidate() |
| | | } |
| | | } |