1 /*
<lambda>null2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.settingslib.spa.widget.chart
18
19 import android.view.ViewGroup
20 import android.widget.LinearLayout
21 import androidx.compose.animation.Crossfade
22 import androidx.compose.foundation.layout.Arrangement
23 import androidx.compose.foundation.layout.Column
24 import androidx.compose.foundation.layout.fillMaxWidth
25 import androidx.compose.foundation.layout.height
26 import androidx.compose.foundation.layout.padding
27 import androidx.compose.foundation.layout.wrapContentHeight
28 import androidx.compose.foundation.layout.wrapContentSize
29 import androidx.compose.material3.MaterialTheme
30 import androidx.compose.runtime.Composable
31 import androidx.compose.ui.Alignment
32 import androidx.compose.ui.Modifier
33 import androidx.compose.ui.graphics.Color
34 import androidx.compose.ui.graphics.toArgb
35 import androidx.compose.ui.unit.dp
36 import androidx.compose.ui.viewinterop.AndroidView
37 import com.github.mikephil.charting.charts.PieChart
38 import com.github.mikephil.charting.data.PieData
39 import com.github.mikephil.charting.data.PieDataSet
40 import com.github.mikephil.charting.data.PieEntry
41
42 /**
43 * The chart settings model for [PieChart].
44 */
45 interface PieChartModel {
46 /**
47 * The chart data list for [PieChart].
48 */
49 val chartDataList: List<PieChartData>
50
51 /**
52 * The center text in the hole of [PieChart].
53 */
54 val centerText: String?
55 get() = null
56 }
57
58 val colorPalette = arrayListOf(
59 ColorPalette.blue.toArgb(),
60 ColorPalette.red.toArgb(),
61 ColorPalette.yellow.toArgb(),
62 ColorPalette.green.toArgb(),
63 ColorPalette.orange.toArgb(),
64 ColorPalette.cyan.toArgb(),
65 Color.Blue.toArgb()
66 )
67
68 data class PieChartData(
69 var value: Float?,
70 var label: String?,
71 )
72
73 @Composable
PieChartnull74 fun PieChart(pieChartModel: PieChartModel) {
75 PieChart(
76 chartDataList = pieChartModel.chartDataList,
77 centerText = pieChartModel.centerText,
78 )
79 }
80
81 @Composable
PieChartnull82 fun PieChart(
83 chartDataList: List<PieChartData>,
84 modifier: Modifier = Modifier,
85 centerText: String? = null,
86 ) {
87 Column(
88 modifier = modifier
89 .fillMaxWidth()
90 .wrapContentHeight(),
91 horizontalAlignment = Alignment.CenterHorizontally,
92 verticalArrangement = Arrangement.Center
93 ) {
94 Column(
95 modifier = Modifier
96 .padding(16.dp)
97 .height(280.dp),
98 horizontalAlignment = Alignment.CenterHorizontally,
99 verticalArrangement = Arrangement.Center
100 ) {
101 val colorScheme = MaterialTheme.colorScheme
102 val labelTextColor = colorScheme.onSurfaceVariant.toArgb()
103 val labelTextSize = MaterialTheme.typography.bodyMedium.fontSize.value
104 val centerTextSize = MaterialTheme.typography.titleLarge.fontSize.value
105 Crossfade(targetState = chartDataList) { pieChartData ->
106 AndroidView(factory = { context ->
107 PieChart(context).apply {
108 // Fixed settings.`
109 layoutParams = LinearLayout.LayoutParams(
110 ViewGroup.LayoutParams.MATCH_PARENT,
111 ViewGroup.LayoutParams.MATCH_PARENT,
112 )
113 this.isRotationEnabled = false
114 this.description.isEnabled = false
115 this.legend.isEnabled = false
116 this.setTouchEnabled(false)
117
118 this.isDrawHoleEnabled = true
119 this.holeRadius = 90.0f
120 this.setHoleColor(Color.Transparent.toArgb())
121 this.setEntryLabelColor(labelTextColor)
122 this.setEntryLabelTextSize(labelTextSize)
123 this.setCenterTextSize(centerTextSize)
124 this.setCenterTextColor(colorScheme.onSurface.toArgb())
125
126 // Customizable settings.
127 this.centerText = centerText
128 }
129 },
130 modifier = Modifier
131 .wrapContentSize()
132 .padding(4.dp), update = {
133 updatePieChartWithData(it, pieChartData)
134 })
135 }
136 }
137 }
138 }
139
updatePieChartWithDatanull140 fun updatePieChartWithData(
141 chart: PieChart,
142 data: List<PieChartData>,
143 ) {
144 val entries = ArrayList<PieEntry>()
145 for (i in data.indices) {
146 val item = data[i]
147 entries.add(PieEntry(item.value ?: 0.toFloat(), item.label ?: ""))
148 }
149
150 val ds = PieDataSet(entries, "")
151 ds.setDrawValues(false)
152 ds.colors = colorPalette
153 ds.sliceSpace = 2f
154 ds.yValuePosition = PieDataSet.ValuePosition.OUTSIDE_SLICE
155 ds.xValuePosition = PieDataSet.ValuePosition.OUTSIDE_SLICE
156 ds.valueLineColor = Color.Transparent.toArgb()
157 ds.valueLinePart1Length = 0.1f
158 ds.valueLinePart2Length = 0f
159
160 val d = PieData(ds)
161 chart.data = d
162 chart.invalidate()
163 }
164