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

commonMain.jetbrains.datalore.plot.builder.assemble.PlotGuidesAssemblerUtil.kt Maven / Gradle / Ivy

There is a newer version: 4.5.3-alpha1
Show newest version
/*
 * Copyright (c) 2020. 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.assemble

import jetbrains.datalore.base.gcommon.base.Preconditions.checkState
import jetbrains.datalore.base.gcommon.base.Strings.isNullOrEmpty
import jetbrains.datalore.base.gcommon.collect.ClosedRange
import jetbrains.datalore.base.values.Color
import jetbrains.datalore.plot.base.Aes
import jetbrains.datalore.plot.base.Scale
import jetbrains.datalore.plot.builder.theme.LegendTheme
import jetbrains.datalore.plot.common.data.SeriesUtil.ensureApplicableRange
import kotlin.math.max

internal object PlotGuidesAssemblerUtil {
    fun mappedRenderedAesToCreateGuides(
        layerTiles: StitchedPlotLayers,
        guideOptionsMap: Map, GuideOptions>
    ): List> {
        if (layerTiles.isLegendDisabled) {
            // ToDo: add support for
            // show_legend = True     : show all aesthetics in legend
            // show_legend = [.. list of aesthetics to show ..]     : show selected aesthetics in legend
            // see: https://ggplot2.tidyverse.org/reference/geom_point.html
            return emptyList()
        }

        val result = ArrayList>()
        for (aes in layerTiles.renderedAes()) {
            if (Aes.noGuideNeeded(aes)) {
                continue
            }
            if (layerTiles.hasConstant(aes)) {
                // constants mask aes mappings
                continue
            }
            if (!layerTiles.hasBinding(aes)) {
                continue
            }
            if (guideOptionsMap.containsKey(aes)) {
                if (guideOptionsMap[aes] === GuideOptions.NONE) {
                    continue
                }
            }

            val scale = layerTiles.getScale(aes)
            val scaleName = scale.name
            if (isNullOrEmpty(scaleName)) {
                continue
            }

            result.add(aes)
        }

        return result
    }

    fun guideDataRangeByAes(
        stitchedLayers: StitchedPlotLayers,
        guideOptionsMap: Map, GuideOptions>
    ): Map, ClosedRange> {
        val guideDomainByAes = HashMap, ClosedRange>()
        val aesSet =
            mappedRenderedAesToCreateGuides(
                stitchedLayers,
                guideOptionsMap
            )
        for (aes in aesSet) {
            val binding = stitchedLayers.getBinding(aes)
            if (stitchedLayers.isNumericData(binding.variable)) {
                val dataRange = stitchedLayers.getDataRange(binding.variable)
                if (dataRange != null) {
                    val scale = stitchedLayers.getScale(aes)

                    val guideDomain =
                        if (scale.isContinuousDomain && scale.hasDomainLimits()) {
                            val limits = scale.domainLimits!!
                            val lowerEnd = if (limits.lowerEnd.isFinite()) limits.lowerEnd else dataRange.lowerEnd
                            val upperEnd = if (limits.upperEnd.isFinite()) limits.upperEnd else dataRange.upperEnd
                            ClosedRange(lowerEnd, max(lowerEnd, upperEnd))
                        } else {
                            dataRange
                        }


                    guideDomainByAes[aes] = guideDomain
                }
            }
        }

        return guideDomainByAes
    }

    fun createColorBarAssembler(
        scaleName: String,
        aes: Aes<*>, dataRangeByAes: Map, ClosedRange>,
        scale: Scale,
        options: ColorBarOptions?,
        theme: LegendTheme
    ): ColorBarAssembler {

        val domain = dataRangeByAes[aes]
        val result = ColorBarAssembler(
            scaleName,
            ensureApplicableRange(domain),
            scale,
            theme
        )
        result.setOptions(options)
        return result
    }

    fun fitsColorBar(aes: Aes<*>, scale: Scale<*>): Boolean {
        return aes.isColor && scale.isContinuous
    }

    fun checkFitsColorBar(aes: Aes<*>, scale: Scale<*>) {
        checkState(aes.isColor, "Color-bar is not applicable to $aes aesthetic")
        checkState(
            scale.isContinuous,
            "Color-bar is only applicable when both domain and color palette are continuous"
        )
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy