Skip to content

Commit 6d0b318

Browse files
Fix #358 Outlier tooltips: the spout sometimes is too long (boxplot).
1 parent c3cbce8 commit 6d0b318

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

future_changes.md

+1
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@
4141
- Wrong direction in colorbars (legend) [[#204](https://github.com/JetBrains/lets-plot/issues/204)].
4242
- geom_jitter: show axis tooltips (same as geom_point) [[#412](https://github.com/JetBrains/lets-plot/issues/412)].
4343
- Memory leak in IDEA caused by a `final void dispose()` method in PlotPanel.
44+
- Outlier tooltips: the spout sometimes is too long (boxplot) [[#358](https://github.com/JetBrains/lets-plot/issues/358)].

plot-builder/src/commonMain/kotlin/jetbrains/datalore/plot/builder/tooltip/layout/LayoutManager.kt

+14-2
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,20 @@ class LayoutManager(
295295
stemX = targetCoordX
296296
}
297297
!(canFitLeft || canFitRight) -> {
298-
tooltipX = 0.0
299-
stemX = targetCoordX
298+
when (myPreferredHorizontalAlignment) {
299+
HorizontalAlignment.LEFT -> {
300+
stemX = targetCoordX - hintSize
301+
tooltipX = stemX + stemLength
302+
}
303+
HorizontalAlignment.RIGHT -> {
304+
stemX = targetCoordX + hintSize
305+
tooltipX = stemX - tooltipWidth - stemLength
306+
}
307+
HorizontalAlignment.CENTER -> {
308+
stemX = targetCoordX
309+
tooltipX = targetCoordX - tooltipWidth / 2
310+
}
311+
}
300312
}
301313
myPreferredHorizontalAlignment == HorizontalAlignment.LEFT && canFitLeft || !canFitRight -> {
302314
tooltipX = leftTooltipPlacement.start()

plot-builder/src/jvmTest/kotlin/plot/builder/tooltip/layout/HorizontalTooltipLayoutTest.kt

+46
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
package jetbrains.datalore.plot.builder.tooltip.layout
77

88
import jetbrains.datalore.base.geometry.DoubleRectangle
9+
import jetbrains.datalore.base.geometry.DoubleVector
910
import jetbrains.datalore.plot.builder.interact.TestUtil.coord
1011
import jetbrains.datalore.plot.builder.interact.TestUtil.size
1112
import jetbrains.datalore.plot.builder.tooltip.layout.LayoutManager.HorizontalAlignment
1213
import jetbrains.datalore.plot.builder.tooltip.layout.LayoutManager.HorizontalAlignment.LEFT
14+
import jetbrains.datalore.plot.builder.tooltip.layout.LayoutManager.HorizontalAlignment.RIGHT
1315
import jetbrains.datalore.plot.builder.tooltip.layout.MeasuredTooltipBuilder.MeasuredTooltipBuilderFactory
1416
import kotlin.test.Test
1517

@@ -197,6 +199,50 @@ internal class HorizontalTooltipLayoutTest : TooltipLayoutTestBase() {
197199
)
198200
}
199201

202+
@Test
203+
fun whenThereIsNotEnoughHorizontalSpaceFromBothSides_AndHorizontalAlignmentIsLeft_ShouldAlignTooltipToRightOfTheLeftBorder() {
204+
val objectRadius = 200.0
205+
val tooltipBuilder = MeasuredTooltipBuilderFactory()
206+
.defaultObjectRadius(objectRadius)
207+
.defaultTipSize(size(80.0, 80.0))
208+
209+
val layoutManagerController = createTipLayoutManagerBuilder(VIEWPORT)
210+
.addTooltip(tooltipBuilder.horizontal(TOOLTIP_KEY, VIEWPORT.center).buildTooltip())
211+
.build()
212+
213+
arrange(layoutManagerController)
214+
215+
val stemX = VIEWPORT.center.x - objectRadius
216+
assertAllTooltips(
217+
expect()
218+
.tooltipX(stemX + NORMAL_STEM_LENGTH)
219+
.stemCoord(DoubleVector(stemX, VIEWPORT.center.y))
220+
)
221+
}
222+
223+
@Test
224+
fun whenThereIsNotEnoughHorizontalSpaceFromBothSides_AndHorizontalAlignmentIsRight_ShouldAlignTooltipToLeftOfTheRightBorder() {
225+
val objectRadius = 200.0
226+
val tipSize = size(80.0, 80.0)
227+
val tooltipBuilder = MeasuredTooltipBuilderFactory()
228+
.defaultObjectRadius(objectRadius)
229+
.defaultTipSize(tipSize)
230+
231+
val layoutManagerController = createTipLayoutManagerBuilder(VIEWPORT)
232+
.preferredHorizontalAlignment(RIGHT)
233+
.addTooltip(tooltipBuilder.horizontal(TOOLTIP_KEY, VIEWPORT.center).buildTooltip())
234+
.build()
235+
236+
arrange(layoutManagerController)
237+
238+
val stemX = VIEWPORT.center.x + objectRadius
239+
assertAllTooltips(
240+
expect()
241+
.tooltipX(stemX - tipSize.x - NORMAL_STEM_LENGTH)
242+
.stemCoord(DoubleVector(stemX, VIEWPORT.center.y))
243+
)
244+
}
245+
200246
companion object {
201247
private const val IGNORED_KEY = "ignored"
202248
private const val TOOLTIP_KEY = "tooltip"

plot-builder/src/jvmTest/kotlin/plot/builder/tooltip/layout/TooltipLayoutTestBase.kt

+6-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ internal open class TooltipLayoutTestBase {
194194

195195
internal class TipLayoutManagerBuilder(private val myViewport: DoubleRectangle) : TooltipDataProvider {
196196
private val myTooltipData = ArrayList<MeasuredTooltip>()
197-
private val myHorizontalAlignment: HorizontalAlignment = LEFT
197+
private var myHorizontalAlignment: HorizontalAlignment = LEFT
198198
private var myCursor = DoubleVector.ZERO
199199

200200
fun cursor(cursor: DoubleVector): TipLayoutManagerBuilder {
@@ -207,6 +207,11 @@ internal open class TooltipLayoutTestBase {
207207
return this
208208
}
209209

210+
fun preferredHorizontalAlignment(horizontalAlignment: HorizontalAlignment): TipLayoutManagerBuilder {
211+
myHorizontalAlignment = horizontalAlignment
212+
return this
213+
}
214+
210215
fun build(): TipLayoutManagerController {
211216
return object : TipLayoutManagerController {
212217
override fun arrange(): List<PositionedTooltip> =

0 commit comments

Comments
 (0)