Added Legend to the Venn Diagram
parent
ae6876022c
commit
244f5a7e80
|
@ -23,8 +23,10 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.ui.geometry.Rect
|
import androidx.compose.ui.geometry.Rect
|
||||||
import androidx.compose.ui.geometry.Size
|
import androidx.compose.ui.geometry.Size
|
||||||
|
import androidx.compose.ui.graphics.Paint
|
||||||
import androidx.compose.ui.graphics.Path
|
import androidx.compose.ui.graphics.Path
|
||||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||||
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.text.*
|
import androidx.compose.ui.text.*
|
||||||
import androidx.compose.ui.unit.Constraints
|
import androidx.compose.ui.unit.Constraints
|
||||||
|
|
||||||
|
@ -257,94 +259,139 @@ fun IntersectionCircles(
|
||||||
val circleRadius = 300f // Fixed radius for both circles
|
val circleRadius = 300f // Fixed radius for both circles
|
||||||
val circleDistance = (1 - intersectionSize) * 2 * circleRadius // Distance between the centers of the 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)) {
|
Row (
|
||||||
// Draw glossary circle
|
modifier = Modifier.fillMaxWidth(),
|
||||||
drawCircle(
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
color = Color(0xFFA1C084),
|
) {
|
||||||
center = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2),
|
|
||||||
radius = circleRadius
|
|
||||||
)
|
|
||||||
|
|
||||||
// Draw code circle
|
drawLegend(100f, 500f)
|
||||||
drawCircle(
|
|
||||||
color = Color(0xFFE9C46A),
|
|
||||||
center = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2),
|
|
||||||
radius = circleRadius
|
|
||||||
)
|
|
||||||
|
|
||||||
|
Canvas(modifier = Modifier.size(500.dp)) {
|
||||||
|
// Draw glossary circle
|
||||||
// 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(
|
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),
|
center = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2),
|
||||||
radius = circleRadius
|
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 { _ ->
|
// Draw intersection with clipping
|
||||||
drawText(
|
drawIntoCanvas { canvas ->
|
||||||
textMeasurer,
|
val path = Path().apply {
|
||||||
word,
|
addOval(
|
||||||
Offset(
|
Rect(
|
||||||
(glossaryCircleCenter.x - circleRadius / 1.5).toFloat(),
|
center = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2),
|
||||||
glossaryCircleCenter.y - circleRadius / 2 + index * 20f
|
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 ->
|
// Draw words on the circles
|
||||||
drawIntoCanvas { _ ->
|
val glossaryCircleCenter = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2)
|
||||||
drawText(
|
val codeCircleCenter = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2)
|
||||||
textMeasurer,
|
|
||||||
word,
|
|
||||||
Offset(
|
|
||||||
codeCircleCenter.x,
|
|
||||||
codeCircleCenter.y - circleRadius / 2 + index * 20f
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
intersectionWords.forEachIndexed { index, word ->
|
glossaryWordsSubset.forEachIndexed { index, word ->
|
||||||
drawIntoCanvas { _ ->
|
drawIntoCanvas { _ ->
|
||||||
drawText(
|
drawText(
|
||||||
textMeasurer,
|
textMeasurer,
|
||||||
word,
|
word,
|
||||||
Offset(
|
Offset(
|
||||||
size.width / 2 - circleDistance / 2 + circleRadius / 2,
|
(glossaryCircleCenter.x - circleRadius / 1.5).toFloat(),
|
||||||
size.height / 2 - circleRadius / 2 + index * 20f
|
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
|
@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)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue