Added Legend to the Venn Diagram

main
Cemal Odabasioglu 2024-02-19 15:39:24 +01:00
parent ae6876022c
commit 244f5a7e80
1 changed files with 114 additions and 67 deletions

View File

@ -23,8 +23,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.text.*
import androidx.compose.ui.unit.Constraints
@ -257,94 +259,139 @@ fun IntersectionCircles(
val circleRadius = 300f // Fixed radius for both circles
val circleDistance = (1 - intersectionSize) * 2 * circleRadius // Distance between the centers of the circles
val textMeasurer = rememberTextMeasurer()
val textMeasurer = rememberTextMeasurer(
)
Canvas(modifier = Modifier.size(500.dp)) {
// Draw glossary circle
drawCircle(
color = Color(0xFFA1C084),
center = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2),
radius = circleRadius
)
Row (
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
// Draw code circle
drawCircle(
color = Color(0xFFE9C46A),
center = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2),
radius = circleRadius
)
drawLegend(100f, 500f)
// Draw intersection with clipping
drawIntoCanvas { canvas ->
val path = Path().apply {
addOval(
Rect(
center = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2),
radius = circleRadius
)
)
}
canvas.save()
canvas.clipPath(path)
Canvas(modifier = Modifier.size(500.dp)) {
// Draw glossary circle
drawCircle(
color = Color(0xFF6E7271),
color = Color(0xFFA1C084),
center = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2),
radius = circleRadius
)
// Draw code circle
drawCircle(
color = Color(0xFFE9C46A),
center = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2),
radius = circleRadius
)
canvas.restore()
}
// Draw words on the circles
val glossaryCircleCenter = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2)
val codeCircleCenter = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2)
glossaryWordsSubset.forEachIndexed { index, word ->
drawIntoCanvas { _ ->
drawText(
textMeasurer,
word,
Offset(
(glossaryCircleCenter.x - circleRadius / 1.5).toFloat(),
glossaryCircleCenter.y - circleRadius / 2 + index * 20f
),
// Draw intersection with clipping
drawIntoCanvas { canvas ->
val path = Path().apply {
addOval(
Rect(
center = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2),
radius = circleRadius
)
)
}
canvas.save()
canvas.clipPath(path)
drawCircle(
color = Color(0xFF6E7271),
center = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2),
radius = circleRadius
)
canvas.restore()
}
}
codeWordsSubset.forEachIndexed { index, word ->
drawIntoCanvas { _ ->
drawText(
textMeasurer,
word,
Offset(
codeCircleCenter.x,
codeCircleCenter.y - circleRadius / 2 + index * 20f
),
)
}
}
// Draw words on the circles
val glossaryCircleCenter = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2)
val codeCircleCenter = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2)
intersectionWords.forEachIndexed { index, word ->
drawIntoCanvas { _ ->
drawText(
textMeasurer,
word,
Offset(
size.width / 2 - circleDistance / 2 + circleRadius / 2,
size.height / 2 - circleRadius / 2 + index * 20f
),
)
glossaryWordsSubset.forEachIndexed { index, word ->
drawIntoCanvas { _ ->
drawText(
textMeasurer,
word,
Offset(
(glossaryCircleCenter.x - circleRadius / 1.5).toFloat(),
glossaryCircleCenter.y - circleRadius / 2 + index * 30f
),
)
}
}
codeWordsSubset.forEachIndexed { index, word ->
drawIntoCanvas { _ ->
drawText(
textMeasurer,
word,
Offset(
codeCircleCenter.x,
codeCircleCenter.y - circleRadius / 2 + index * 30f
),
)
}
}
intersectionWords.forEachIndexed { index, word ->
drawIntoCanvas { _ ->
drawText(
textMeasurer,
word,
Offset(
size.width / 2 - circleDistance / 2 + circleRadius / 2,
size.height / 2 - circleRadius / 2 + index * 30f
),
)
}
}
}
}
}
@OptIn(ExperimentalTextApi::class)
@Composable
fun vennDiagramLegend() {
fun drawLegend(canvasWidth: Float, canvasHeight: Float) {
val legendTextSize = 20f
val legendItemHeight = 40f
val legendStartOffset = Offset(x = canvasWidth, y = canvasHeight / 2)
val legendItems = listOf(
LegendItem("Mots du glossaire", Color(0xFFA1C084)),
LegendItem("Mots du code", Color(0xFFE9C46A)),
LegendItem("Mots du glossaire et du code", Color(0xFF6E7271))
)
val textMeasurer = rememberTextMeasurer()
Canvas(modifier = Modifier.size(width = 50.dp, height = 500.dp)) {
legendItems.forEachIndexed { index, legendItem ->
drawRect(
color = legendItem.color,
topLeft = legendStartOffset + Offset(x=0f, y = index * legendItemHeight),
size = Size(20f, 20f)
)
drawIntoCanvas { _ ->
drawText(
textMeasurer,
legendItem.label,
Offset(
-90f,
legendStartOffset.y + index * legendItemHeight
),
)
}
}
}
}
data class LegendItem(val label: String, val color: Color)