in plot-base/src/commonMain/kotlin/org/jetbrains/letsPlot/core/plot/base/geom/annotation/CrossBarAnnotation.kt [21:86]
fun build(
root: SvgRoot,
rectangles: Map<DataPointAesthetics, DoubleRectangle>,
midLines: Map<Int, DoubleSegment>,
fatten: Double,
coord: CoordinateSystem,
ctx: GeomContext
) {
val annotation = ctx.annotation ?: return
val viewPort = GeomBase.overallAesBounds(ctx).let(coord::toClient) ?: return
val padding = annotation.textStyle.size / 2
val isHorizontallyOriented = ctx.flipped
rectangles
.map { (aes, rect) -> Triple(aes, rect, midLines[aes.index()]) }
.forEach { (aes, rect, midLine) ->
val text = annotation.getAnnotationText(aes.index(), ctx.plotContext)
val textSize = AnnotationUtil
.textSizeGetter(annotation.textStyle, ctx)
.invoke(text, aes)
val midLineStrokeWidth = AesScaling.strokeWidth(aes) * fatten
var location = findTextLocation(
viewPort,
rect,
midLine,
midLineStrokeWidth,
textSize.add(DoubleVector(2 * padding, 2 * padding)),
isHorizontallyOriented
)
val textRect = DoubleRectangle(
location.subtract(textSize.mul(0.5)),
textSize
)
val (textColor, alpha) = textColorAndLabelAlpha(
annotation, aes.color(), aes.fill(),
insideGeom = rect.contains(textRect)
)
// separate label for each line
val labels = Label.splitLines(text)
// Adjust location to center the first line vertically
location = location.subtract(DoubleVector(0.0, annotation.textStyle.size * labels.size / 2))
labels.map { line ->
AnnotationUtil.createLabelElement(
line,
location,
textParams = AnnotationUtil.TextParams(
style = annotation.textStyle,
color = textColor,
hjust = "middle",
vjust = "top",
fill = ctx.backgroundColor,
alpha = alpha
),
geomContext = ctx,
).also {
location = location.add(DoubleVector(0.0, annotation.textStyle.size))
}
}.forEach(root::add)
}
}