All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.jetbrains.datalore.plot.base.pos.StackPos.kt Maven / Gradle / Ivy

There is a newer version: 4.5.3-alpha1
Show newest version
/*
 * 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.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