@@ -13,10 +13,12 @@ import androidx.compose.foundation.background
1313import androidx.compose.foundation.border
1414import androidx.compose.foundation.layout.Arrangement
1515import androidx.compose.foundation.layout.Box
16+ import androidx.compose.foundation.layout.BoxWithConstraints
1617import androidx.compose.foundation.layout.Column
1718import androidx.compose.foundation.layout.Row
1819import androidx.compose.foundation.layout.fillMaxWidth
1920import androidx.compose.foundation.layout.height
21+ import androidx.compose.foundation.layout.offset
2022import androidx.compose.foundation.layout.padding
2123import androidx.compose.foundation.layout.width
2224import androidx.compose.foundation.relocation.BringIntoViewRequester
@@ -259,6 +261,8 @@ internal fun DistributionBar(score: Double, standard: GradeStandard) {
259261 val displayDistributions = distributions.asReversed()
260262 val total = distributions.sumOf { it.count }.coerceAtLeast(1 )
261263 val mine = distributions.firstOrNull { it.isMine }
264+ val weights = displayDistributions.map { (it.count.toFloat() / total).coerceAtLeast(0.02f ) }
265+ val mineIndex = displayDistributions.indexOfFirst { it.isMine }
262266 Column (verticalArrangement = Arrangement .spacedBy(8 .dp)) {
263267 Row (verticalAlignment = Alignment .CenterVertically ) {
264268 Text (
@@ -274,43 +278,48 @@ internal fun DistributionBar(score: Double, standard: GradeStandard) {
274278 fontWeight = FontWeight .SemiBold ,
275279 )
276280 }
277- Row (
281+ BoxWithConstraints (
278282 modifier = Modifier
279283 .fillMaxWidth()
280284 .height(24 .dp),
281- horizontalArrangement = Arrangement .spacedBy(2 .dp),
282285 ) {
283- displayDistributions.forEach { item ->
284- val weight = (item.count.toFloat() / total).coerceAtLeast(0.02f )
286+ val gap = 2 .dp
287+ val markerSize = 8 .dp
288+ Row (
289+ modifier = Modifier .fillMaxWidth().height(24 .dp),
290+ horizontalArrangement = Arrangement .spacedBy(gap),
291+ ) {
292+ displayDistributions.forEachIndexed { index, item ->
293+ Box (
294+ modifier = Modifier
295+ .weight(weights[index])
296+ .height(24 .dp)
297+ .background(distributionColor(item.label), RoundedCornerShape (5 .dp)),
298+ )
299+ }
300+ }
301+ if (mineIndex >= 0 ) {
302+ val weightTotal = weights.sum().coerceAtLeast(0.001f )
303+ val gapWidth = gap * (displayDistributions.size - 1 ).coerceAtLeast(0 ).toFloat()
304+ val weightedWidth = (maxWidth - gapWidth).coerceAtLeast(0 .dp)
305+ val beforeWeight = weights.take(mineIndex).sum()
306+ val markerCenter = gap * mineIndex.toFloat() +
307+ weightedWidth * ((beforeWeight + weights[mineIndex] / 2f ) / weightTotal)
308+ val markerX = (markerCenter - markerSize / 2f )
309+ .coerceIn(0 .dp, (maxWidth - markerSize).coerceAtLeast(0 .dp))
285310 Box (
286311 modifier = Modifier
287- .weight(weight)
288- .height(24 .dp)
289- .background(distributionColor(item.label), RoundedCornerShape (5 .dp)),
290- contentAlignment = Alignment .Center ,
291- ) {
292- if (item.isMine) {
293- Text (
294- modifier = Modifier
295- .background(
296- color = MaterialTheme .colorScheme.surface,
297- shape = RoundedCornerShape (999 .dp)
298- )
299- .border(
300- width = 1 .dp,
301- color = MaterialTheme .colorScheme.outlineVariant,
302- shape = RoundedCornerShape (999 .dp)
303- )
304- .padding(horizontal = 8 .dp, vertical = 2 .dp),
305- text = " 我" ,
306- style = MaterialTheme .typography.labelSmall.copy(
307- fontWeight = FontWeight .SemiBold ,
308- letterSpacing = 0.2 .sp
309- ),
310- color = MaterialTheme .colorScheme.onSurface
311- )
312- }
313- }
312+ .offset(x = markerX)
313+ .width(markerSize)
314+ .height(markerSize)
315+ .align(Alignment .CenterStart )
316+ .background(MaterialTheme .colorScheme.primary, RoundedCornerShape (999 .dp))
317+ .border(
318+ width = 1 .dp,
319+ color = MaterialTheme .colorScheme.surface,
320+ shape = RoundedCornerShape (999 .dp)
321+ ),
322+ )
314323 }
315324 }
316325 displayDistributions.forEach { item ->
0 commit comments