@@ -16,6 +16,7 @@ import androidx.compose.runtime.remember
1616import androidx.compose.runtime.rememberCoroutineScope
1717import androidx.compose.runtime.setValue
1818import androidx.compose.ui.Modifier
19+ import androidx.compose.ui.geometry.Offset
1920import androidx.compose.ui.geometry.Rect
2021import androidx.compose.ui.geometry.isUnspecified
2122import androidx.compose.ui.graphics.Color
@@ -24,9 +25,11 @@ import androidx.compose.ui.graphics.PathMeasure
2425import androidx.compose.ui.graphics.drawscope.Fill
2526import androidx.compose.ui.graphics.drawscope.Stroke
2627import androidx.compose.ui.input.pointer.pointerInput
28+ import ir.ehsannarmani.compose_charts.extensions.getAngleInDegree
29+ import ir.ehsannarmani.compose_charts.extensions.isDegreeBetween
30+ import ir.ehsannarmani.compose_charts.extensions.isInsideCircle
2731import ir.ehsannarmani.compose_charts.models.Pie
2832import kotlinx.coroutines.launch
29- import kotlin.math.atan2
3033import kotlin.random.Random
3134
3235@Composable
@@ -52,11 +55,15 @@ fun PieChart(
5255
5356 val scope = rememberCoroutineScope()
5457
58+ var pieChartCenter by remember {
59+ mutableStateOf(Offset .Zero )
60+ }
61+
5562 var details by remember {
5663 mutableStateOf(emptyList<PieDetails >())
5764 }
5865 val pieces = remember {
59- mutableListOf<Pair < String , Rect > >()
66+ mutableListOf<PiePiece >()
6067 }
6168
6269 val pathMeasure = remember {
@@ -132,8 +139,14 @@ fun PieChart(
132139 Canvas (modifier = modifier
133140 .pointerInput(Unit ) {
134141 detectTapGestures { offset ->
135- pieces
136- .firstOrNull { it.second.contains(offset) }
142+ val angleInDegree = getAngleInDegree(
143+ touchTapOffset = offset,
144+ pieceOffset = pieChartCenter
145+ )
146+
147+ pieces.firstOrNull { piece ->
148+ isDegreeBetween(angleInDegree, piece.startFromDegree, piece.endToDegree)
149+ && isInsideCircle(offset, pieChartCenter, piece.radius) }
137150 ?.let {
138151 val (id, _) = it
139152 details.find { it.id == id }
@@ -144,6 +157,8 @@ fun PieChart(
144157 }
145158 }
146159 ) {
160+ pieChartCenter = center
161+
147162 val radius: Float = when (style) {
148163 is Pie .Style .Fill -> {
149164 (minOf(size.width, size.height) / 2 )
@@ -165,6 +180,15 @@ fun PieChart(
165180 val piecePath = if (degree >= 360.0 ) {
166181 // draw circle instead of arc
167182
183+ pieces.add(
184+ PiePiece (
185+ id = detail.id,
186+ radius = radius * detail.scale.value,
187+ startFromDegree = 0f ,
188+ endToDegree = 360f
189+ )
190+ )
191+
168192 Path ().apply {
169193 addOval(
170194 oval = Rect (
@@ -206,11 +230,18 @@ fun PieChart(
206230 (size.height / 2 )
207231 )
208232 }
233+
234+ pieces.add(
235+ PiePiece (
236+ id = detail.id,
237+ radius = radius * detail.scale.value,
238+ startFromDegree = arcStart,
239+ endToDegree = if (arcStart + arcSweep >= 360f ) 360f else arcStart + arcSweep,
240+ )
241+ )
209242 piecePath
210243 }
211- val rect = piecePath.getBounds()
212244
213- pieces.add(detail.id to rect)
214245 drawPath(
215246 path = piecePath,
216247 color = detail.color.value,
@@ -227,4 +258,11 @@ private data class PieDetails(
227258 val color : Animatable <Color , AnimationVector4D > = Animatable (pie.color),
228259 val scale : Animatable <Float , AnimationVector1D > = Animatable (1f),
229260 val space : Animatable <Float , AnimationVector1D > = Animatable (0f)
230- )
261+ )
262+
263+ private data class PiePiece (
264+ val id : String ,
265+ val radius : Float ,
266+ val startFromDegree : Float ,
267+ val endToDegree : Float ,
268+ )
0 commit comments