commonMain.jetbrains.datalore.plot.base.pos.StackPos.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lets-plot-common Show documentation
Show all versions of lets-plot-common Show documentation
Lets-Plot JVM package without rendering part
/*
* 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.base.pos
import jetbrains.datalore.base.geometry.DoubleVector
import jetbrains.datalore.base.values.Pair
import jetbrains.datalore.plot.base.Aesthetics
import jetbrains.datalore.plot.base.DataPointAesthetics
import jetbrains.datalore.plot.base.GeomContext
import jetbrains.datalore.plot.base.PositionAdjustment
import jetbrains.datalore.plot.base.util.MutableDouble
import jetbrains.datalore.plot.common.data.SeriesUtil
internal abstract class StackPos(aes: Aesthetics) :
PositionAdjustment {
private val myOffsetByIndex: Map
init {
myOffsetByIndex = mapIndexToOffset(aes)
}
protected abstract fun mapIndexToOffset(aes: Aesthetics): Map
override fun translate(v: DoubleVector, p: DataPointAesthetics, ctx: GeomContext): DoubleVector {
return v.add(DoubleVector(0.0, myOffsetByIndex[p.index()]!!))
}
override fun handlesGroups(): Boolean {
return PositionAdjustments.Meta.STACK.handlesGroups()
}
private class SplitPositiveNegative internal constructor(aes: Aesthetics) : StackPos(aes) {
override fun mapIndexToOffset(aes: Aesthetics): Map {
val offsetByIndex = HashMap()
val negPosBaseByBin = HashMap>()
for (i in 0 until aes.dataPointCount()) {
val dataPoint = aes.dataPointAt(i)
val x = dataPoint.x()
if (SeriesUtil.isFinite(x)) {
if (!negPosBaseByBin.containsKey(x)) {
negPosBaseByBin[x!!] = Pair(
MutableDouble(0.0),
MutableDouble(0.0)
)
}
val y = dataPoint.y()
if (SeriesUtil.isFinite(y)) {
val pair = negPosBaseByBin[x]!!
val offset: Double
if (y!! >= 0) {
offset = pair.second.getAndAdd(y)
} else {
offset = pair.first.getAndAdd(y)
}
offsetByIndex[i] = offset
}
}
}
return offsetByIndex
}
}
private class SumPositiveNegative internal constructor(aes: Aesthetics) : StackPos(aes) {
override fun mapIndexToOffset(aes: Aesthetics): Map {
val offsetByIndex = HashMap()
val baseByBin = HashMap()
for (i in 0 until aes.dataPointCount()) {
val dataPointAes = aes.dataPointAt(i)
val x = dataPointAes.x()!!
if (SeriesUtil.isFinite(x)) {
if (!baseByBin.containsKey(x)) {
baseByBin[x] = MutableDouble(0.0)
}
val y = dataPointAes.y()!!
if (SeriesUtil.isFinite(y)) {
val base = baseByBin[x]!!
val offset = base.getAndAdd(y)
offsetByIndex[i] = offset
}
}
}
return offsetByIndex
}
}
companion object {
fun splitPositiveNegative(aes: Aesthetics): PositionAdjustment {
return SplitPositiveNegative(aes)
}
fun sumPositiveNegative(aes: Aesthetics): PositionAdjustment {
return SumPositiveNegative(aes)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy