commonMain.jetbrains.datalore.plot.builder.PlotTooltipHelper.kt Maven / Gradle / Ivy
/*
* Copyright (c) 2019. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/
package jetbrains.datalore.plot.builder
import jetbrains.datalore.base.geometry.DoubleRectangle
import jetbrains.datalore.base.geometry.DoubleVector
import jetbrains.datalore.plot.base.interact.GeomTargetLocator
import jetbrains.datalore.plot.base.interact.GeomTargetLocator.LookupResult
import jetbrains.datalore.plot.builder.interact.TooltipSpec
import jetbrains.datalore.plot.builder.interact.TooltipSpecFactory
import jetbrains.datalore.plot.builder.interact.loc.LocatedTargetsPicker
import jetbrains.datalore.plot.builder.interact.loc.TransformedTargetLocator
internal class PlotTooltipHelper {
private val myTileInfos = ArrayList()
fun removeAllTileInfos() {
myTileInfos.clear()
}
fun addTileInfo(geomBounds: DoubleRectangle, targetLocators: List) {
val tileInfo = TileInfo(
geomBounds,
targetLocators
)
myTileInfos.add(tileInfo)
}
fun createTooltipSpecs(plotCoord: DoubleVector): List {
val tileInfo = findTileInfo(plotCoord) ?: return emptyList()
val lookupResults = tileInfo.findTargets(plotCoord)
return createTooltipSpecs(lookupResults, tileInfo.axisOrigin)
}
fun getGeomBounds(plotCoord: DoubleVector): DoubleRectangle? {
val tileInfo = findTileInfo(plotCoord) ?: return null
return tileInfo.geomBounds
}
private fun findTileInfo(plotCoord: DoubleVector): TileInfo? {
for (tileInfo in myTileInfos) {
if (tileInfo.contains(plotCoord)) {
return tileInfo
}
}
return null
}
private fun createTooltipSpecs(lookupResults: List, axisOrigin: DoubleVector): List {
val tooltipSpecs = ArrayList()
lookupResults.forEach { result ->
val factory = TooltipSpecFactory(result.contextualMapping, axisOrigin)
result.targets.forEach { geomTarget -> tooltipSpecs.addAll(factory.create(geomTarget)) }
}
return tooltipSpecs
}
private class TileInfo(
internal val geomBounds: DoubleRectangle,
targetLocators: List
) {
private val myTargetLocators = targetLocators.map { TileTargetLocator(it) }
internal val axisOrigin: DoubleVector
get() = DoubleVector(geomBounds.left, geomBounds.bottom)
internal fun findTargets(plotCoord: DoubleVector): List {
val targetsPicker = LocatedTargetsPicker().apply {
for (locator in myTargetLocators) {
val result = locator.search(plotCoord)
if (result != null) {
addLookupResult(result, plotCoord)
}
}
}
return targetsPicker.picked
}
internal operator fun contains(plotCoord: DoubleVector): Boolean {
return geomBounds.contains(plotCoord)
}
private inner class TileTargetLocator(locator: GeomTargetLocator) : TransformedTargetLocator(locator) {
override fun convertToTargetCoord(coord: DoubleVector): DoubleVector {
return coord.subtract(geomBounds.origin)
}
override fun convertToPlotCoord(coord: DoubleVector): DoubleVector {
return coord.add(geomBounds.origin)
}
override fun convertToPlotDistance(distance: Double): Double {
return distance
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy