in plot-builder/src/commonMain/kotlin/org/jetbrains/letsPlot/core/plot/builder/frame/FrameOfReferenceProviderBase.kt [96:168]
override fun createMarginalFrames(
tileLayoutInfo: TileLayoutInfo,
coordProvider: CoordProvider,
plotBackground: Color,
debugDrawing: Boolean
): Map<MarginSide, FrameOfReference> {
if (domainByMargin.isEmpty()) {
return emptyMap()
}
check(!coordProvider.flipped) {
"`flipped` corrdinate system is not supported on plots with marginal layers."
}
val inner = tileLayoutInfo.geomInnerBounds
val outer = tileLayoutInfo.geomOuterBounds
val origins = mapOf(
MarginSide.LEFT to DoubleVector(outer.left, inner.top),
MarginSide.TOP to DoubleVector(inner.left, outer.top),
MarginSide.RIGHT to DoubleVector(inner.right, inner.top),
MarginSide.BOTTOM to DoubleVector(inner.left, inner.bottom),
)
val sizes = mapOf(
MarginSide.LEFT to DoubleVector(max(0.0, inner.left - outer.left), inner.height),
MarginSide.TOP to DoubleVector(inner.width, max(0.0, inner.top - outer.top)),
MarginSide.RIGHT to DoubleVector(max(0.0, outer.right - inner.right), inner.height),
MarginSide.BOTTOM to DoubleVector(inner.width, max(0.0, outer.bottom - inner.bottom)),
)
val boundsByMargin = origins.mapValues { (margin, origin) ->
DoubleRectangle(origin, sizes.getValue(margin))
}
// Below use any of horizontal/vertical axis info in the "quad".
// ToDo: with non-rectangular coordinates this might not work as axis length (for example) might be different
// for top and botto, axis.
val hAxisLayoutInfo = tileLayoutInfo.axisInfos.bottom
?: tileLayoutInfo.axisInfos.top
?: throw IllegalStateException("No top/bottom axis info.")
val vAxisLayoutInfo = tileLayoutInfo.axisInfos.left
?: tileLayoutInfo.axisInfos.right
?: throw IllegalStateException("No left/right axis info.")
return domainByMargin.mapValues { (side, domain) ->
val hDomain = when (side) {
MarginSide.LEFT, MarginSide.RIGHT -> domain
MarginSide.TOP, MarginSide.BOTTOM -> hAxisLayoutInfo.axisDomain
}
val vDomain = when (side) {
MarginSide.LEFT, MarginSide.RIGHT -> vAxisLayoutInfo.axisDomain
MarginSide.TOP, MarginSide.BOTTOM -> domain
}
val marginCoordProvider = MarginalLayerCoordProvider()
val clientSize = sizes.getValue(side)
val adjustedDomain = DoubleRectangle(hDomain, vDomain)
val coord = marginCoordProvider.createCoordinateSystem(
adjustedDomain = adjustedDomain,
clientSize = clientSize,
)
MarginalFrameOfReference(
plotContext,
boundsByMargin.getValue(side),
adjustedDomain = adjustedDomain,
coord,
plotBackground,
debugDrawing,
)
}
}