Skip to content

Commit

Permalink
Fix position of bar annotation when specifying a reverse scale.
Browse files Browse the repository at this point in the history
  • Loading branch information
OLarionova-HORIS committed Mar 27, 2024
1 parent 0bcf2d1 commit a84afe6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import demoAndTestShared.parsePlotSpec
class BarAnnotations {
fun plotSpecList(): List<MutableMap<String, Any>> {
return listOf(
//barPlot(grouped = false, flip = false),
barPlot(grouped = false, flip = false),
barPlot(grouped = false, flip = false, reversed = true),

barPlot("dodge", flip = false),
barPlot("stack", flip = false),
barPlot("stack", flip = false, yLim = "[3, 30]"),
Expand All @@ -20,16 +22,16 @@ class BarAnnotations {
//barPlot("dodge", flip = true),
//barPlot("stack", flip = true),
barPlot("fill", flip = true),
barPlot("fill", flip = true, yLim = "[0.4, 0.8]"),
//barPlot("fill", flip = true, yLim = "[0.4, 0.8]"),

withNegativeValues("stack", flip = false),
withNegativeValues("stack", flip = false, yLim = "[2, 8]"),
//withNegativeValues("fill", flip = false),
//withNegativeValues("dodge", flip = false),

//withNegativeValues("stack", flip = true),
withNegativeValues("fill", flip = true),
withNegativeValues("fill", flip = true, yLim = "[-0.5, 0.5]"),
//withNegativeValues("fill", flip = true),
//withNegativeValues("fill", flip = true, yLim = "[-0.5, 0.5]"),
//withNegativeValues("dodge", flip = true),
)
}
Expand All @@ -45,20 +47,24 @@ class BarAnnotations {
position: String = "stack",
flip: Boolean = false,
grouped: Boolean = true,
yLim: String? = null
yLim: String? = null,
reversed: Boolean = false
): MutableMap<String, Any> {
val coordSpec = when {
flip -> "'coord': {'name': 'flip', 'flip': true, 'ylim': $yLim},"
yLim != null -> "'coord': {'name': 'cartesian', 'ylim': $yLim},"
else -> ""
}
val mappingSpec = "'x': 'x'" + if (grouped) ", 'fill': 'v'" else ""
val scales = if (reversed) "'scales': [{'aesthetic': 'y', 'trans': 'reverse'}]," else ""

val spec = """
{
'kind': 'plot',
'ggtitle': { 'text': 'position=\'$position\', coord_cartesian(ylim=$yLim)'},
$coordSpec
'mapping': { $mappingSpec },
$scales
'layers': [
{
'geom': 'bar',
Expand All @@ -83,18 +89,25 @@ class BarAnnotations {
"value" to listOf(0.5, 5, -1.5, 3, 1, 2, 4, 0.5, -1, 6, 5, -0.2, 5, -2, 5, 4)
)

private fun withNegativeValues(position: String, flip: Boolean, yLim: String? = null): MutableMap<String, Any> {
private fun withNegativeValues(
position: String,
flip: Boolean,
yLim: String? = null,
reversed: Boolean = false
): MutableMap<String, Any> {
val coordSpec = when {
flip -> "'coord': {'name': 'flip', 'flip': true, 'ylim': $yLim},"
yLim != null -> "'coord': {'name': 'cartesian', 'ylim': $yLim},"
else -> ""
}
val scales = if (reversed) "'scales': [{'aesthetic': 'y', 'trans': 'reverse'}]," else ""
val spec = """
{
'kind': 'plot',
'ggtitle': { 'text': 'position=\'$position\', coord_cartesian(ylim=$yLim)'},
'mapping': { 'x': 'x', 'y': 'value', 'fill': 'group' },
$coordSpec
$scales
'layers': [
{
'geom': 'bar',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ object BarAnnotation {
?.intersect(viewPort) // use the visible part of bar to place annotation on it
?: return@iterateRectangleGeometry

val isNegative = rect.dimension.y < 0
rectangles.add(Triple(p, clientRect, isNegative))
val isUpsideDown = with(rect) { dimension.y < 0 || top < 0 } // bar with base at the top
rectangles.add(Triple(p, clientRect, isUpsideDown))
}

rectangles
Expand All @@ -110,7 +110,7 @@ object BarAnnotation {
.sortedBy { (_, rect) ->
if (isHorizontallyOriented) rect.center.x else rect.center.y
}
.forEachIndexed { index, (p, barRect, isNegative) ->
.forEachIndexed { index, (p, barRect, isUpsideDown) ->
val text = annotation.getAnnotationText(p.index(), ctx.plotContext)
val textSize = AnnotationUtil.textSizeGetter(annotation.textStyle, ctx).invoke(text, p)

Expand All @@ -122,7 +122,7 @@ object BarAnnotation {
padding,
viewPort,
isHorizontallyOriented,
isNegative
isUpsideDown
)
?: return@forEachIndexed

Expand Down Expand Up @@ -182,7 +182,7 @@ object BarAnnotation {
padding: Double,
viewPort: DoubleRectangle,
isHorizontallyOriented: Boolean,
isNegative: Boolean
isUpsideDown: Boolean
): Pair<Text.HorizontalAnchor, DoubleRectangle>? {

val coordSelector: (DoubleVector) -> Double =
Expand All @@ -191,9 +191,10 @@ object BarAnnotation {
var insideBar = when {
barsCount == 1 -> {
// use left (for horizontally orientated) or bottom (of the vertical bar)
if (isHorizontallyOriented) PlacementInsideBar.MIN else PlacementInsideBar.MAX
(if (isHorizontallyOriented) PlacementInsideBar.MIN else PlacementInsideBar.MAX).let {
if (isUpsideDown) it.flip() else it
}
}

index == 0 -> PlacementInsideBar.MIN
index == barsCount - 1 -> PlacementInsideBar.MAX
else -> PlacementInsideBar.MIDDLE
Expand Down Expand Up @@ -231,7 +232,7 @@ object BarAnnotation {
if (barsCount == 1) {
// move to the right (for horizontally orientated) or to the top (of the vertical bar)
insideBar = if (isHorizontallyOriented) PlacementInsideBar.MAX else PlacementInsideBar.MIN
if (isNegative) insideBar = insideBar.flip()
if (isUpsideDown) insideBar = insideBar.flip()
}

fun DoubleRectangle.moveTo(value: Double): DoubleRectangle {
Expand Down

0 comments on commit a84afe6

Please sign in to comment.