Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import androidx.compose.ui.graphics.PathOperation
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
import com.netguru.multiplatform.charts.ChartAnimation
import com.netguru.multiplatform.charts.StartAnimation
import com.netguru.multiplatform.charts.mapValueToDifferentRange
Expand All @@ -26,6 +30,7 @@ import com.netguru.multiplatform.charts.pie.PieDefaults.START_ANGLE
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.min
import kotlin.math.roundToInt
import kotlin.math.sin

data class PieChartData(val name: String, val value: Double, val color: Color)
Expand Down Expand Up @@ -79,6 +84,15 @@ fun PieChart(
)
)
}
val textMeasurer = rememberTextMeasurer()
val textLayouts = sweepAngles.mapIndexed { index, _ ->
val percent = (data[index].value / sumOfData * 100).roundToInt()
val text = "$percent%"
val layoutResult = textMeasurer.measure(
text = AnnotatedString(text),
)
layoutResult
}

Box(
modifier = modifier
Expand All @@ -97,6 +111,13 @@ fun PieChart(
sweepAngle = sweepAngle.toFloat(),
config = config,
)
if (config.showPercentages) {
drawPercentageLabel(
textLayoutResult = textLayouts[index],
startAngle = startAngle,
sweepAngle = sweepAngle
)
}
startAngle += sweepAngle
}
}
Expand Down Expand Up @@ -136,6 +157,27 @@ private fun DrawScope.drawArc(
)
}

private fun DrawScope.drawPercentageLabel(
textLayoutResult: TextLayoutResult,
startAngle: Double,
sweepAngle: Double,
) {
val midAngle = startAngle + sweepAngle / 2
val angleRad = Math.toRadians(midAngle)
val radius = size.minDimension / 2f * 0.65f

val x = center.x + cos(angleRad).toFloat() * radius
val y = center.y + sin(angleRad).toFloat() * radius

drawText(
textLayoutResult = textLayoutResult,
topLeft = Offset(
x - textLayoutResult.size.width / 2f,
y - textLayoutResult.size.height / 2f
)
)
}

private const val RIGHT_ANGLE = 90f
private const val HALF_CIRCLE_ANGLE = 180f
private const val FULL_CIRCLE_ANGLE = 360f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ data class PieChartConfig(
val legendIconSize: Dp = PieDefaults.LEGEND_ICON_SIZE,
val legendOrientation: LegendOrientation = LegendOrientation.HORIZONTAL,
val numberOfColsInLegend: Int = PieDefaults.NUMBER_OF_COLS_IN_LEGEND,
val showPercentages: Boolean = false
)

enum class LegendIcon {
Expand Down