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

commonMain.jetbrains.datalore.plot.builder.assemble.PlotAssemblerUtil.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.interval.DoubleSpan
import jetbrains.datalore.base.values.Color
import jetbrains.datalore.plot.base.Aes
import jetbrains.datalore.plot.base.PlotContext
import jetbrains.datalore.plot.base.Scale
import jetbrains.datalore.plot.base.ScaleMapper
import jetbrains.datalore.plot.builder.assemble.PlotGuidesAssemblerUtil.checkFitsColorBar
import jetbrains.datalore.plot.builder.assemble.PlotGuidesAssemblerUtil.createColorBarAssembler
import jetbrains.datalore.plot.builder.assemble.PlotGuidesAssemblerUtil.fitsColorBar
import jetbrains.datalore.plot.builder.assemble.PlotGuidesAssemblerUtil.mappedRenderedAesToCreateGuides
import jetbrains.datalore.plot.builder.layout.*
import jetbrains.datalore.plot.builder.theme.AxisTheme
import jetbrains.datalore.plot.builder.theme.FacetsTheme
import jetbrains.datalore.plot.builder.theme.LegendTheme

internal object PlotAssemblerUtil {

    private fun updateAesRangeMap(
        aes: Aes<*>,
        range: DoubleSpan?,
        rangeByAes: MutableMap, DoubleSpan>
    ) {
        @Suppress("NAME_SHADOWING")
        var range = range
        if (range != null) {
            val wasRange = rangeByAes[aes]
            if (wasRange != null) {
                range = wasRange.union(range)
            }
            rangeByAes[aes] = range
        }
    }

//    fun createLegends(
////        layersByPanel: List>,
////        scaleMap: TypedScaleMap,
//        plotContext: PlotContext,
//        scaleMappersNP: Map, ScaleMapper<*>>,
//        guideOptionsMap: Map, GuideOptions>,
//        theme: LegendTheme
//    ): List {
//
//        // stitch together layers from all panels
//        var planeCount = 0
//        if (layersByPanel.isNotEmpty()) {
//            planeCount = layersByPanel[0].size
//        }
//
//        val stitchedLayersList = ArrayList()
//        for (i in 0 until planeCount) {
//            val layersOnPlane = ArrayList()
//
//            // collect layer[i] chunks from all panels
//            for (panelLayers in layersByPanel) {
//                layersOnPlane.add(panelLayers[i])
//            }
//
//            stitchedLayersList.add(
//                StitchedPlotLayers(
//                    layersOnPlane
//                )
//            )
//        }
//
//        val transformedDomainByAes = HashMap, DoubleSpan>()
//        for (stitchedPlotLayers in stitchedLayersList) {
//            val layerTransformedDomainByAes = guideTransformedDomainByAes(
//                stitchedPlotLayers,
//                scaleMap,
//                guideOptionsMap
//            )
//            for ((aes, transformedDomain) in layerTransformedDomainByAes) {
//                updateAesRangeMap(
//                    aes,
//                    transformedDomain,
//                    transformedDomainByAes
//                )
//            }
//        }
//
//        return createLegends(
//            stitchedLayersList,
//            transformedDomainByAes,
//            scaleMap,
//
//            scaleMappersNP,
//            guideOptionsMap,
//            theme
//        )
//    }

    //    private fun createLegends(
    fun createLegends(
//        stitchedLayersList: List,
//        transformedDomainByAes: Map, DoubleSpan>,
//        scaleMap: TypedScaleMap,
        ctx: PlotContext,
        scaleMappersNP: Map, ScaleMapper<*>>,
        guideOptionsMap: Map, GuideOptions>,
        theme: LegendTheme
    ): List {

        val legendAssemblerByTitle = LinkedHashMap()
        val colorBarAssemblerByTitle = LinkedHashMap()

//        for (stitchedLayers in stitchedLayersList) {
        for (contextLayer in ctx.layers) {
            val layerConstantByAes = HashMap, Any>()
            for (aes in contextLayer.renderedAes()) {
                if (contextLayer.hasConstant(aes)) {
                    layerConstantByAes[aes] = contextLayer.getConstant(aes)!!
                }
            }

//            val layerBindingsByScaleName = LinkedHashMap>()
            val aesListByScaleName = LinkedHashMap>>()
            val aesList = mappedRenderedAesToCreateGuides(contextLayer, guideOptionsMap)
            for (aes in aesList) {
                var colorBar = false
//                val binding = contextLayer.getBinding(aes)
                val scale = ctx.getScale(aes)
                val scaleName = scale.name
                if (guideOptionsMap.containsKey(aes)) {
                    val guideOptions = guideOptionsMap[aes]
                    if (guideOptions is ColorBarOptions) {
                        checkFitsColorBar(aes, scale)
                        colorBar = true
                        @Suppress("UNCHECKED_CAST")
                        colorBarAssemblerByTitle[scaleName] = createColorBarAssembler(
                            scaleName,
//                            transformedDomainByAes.getValue(aes),
                            ctx.overallTransformedDomain(aes),
                            scale as Scale,
                            scaleMappersNP.getValue(aes) as ScaleMapper,
                            guideOptions,
                            theme
                        )
                    }
                } else if (fitsColorBar(aes, scale)) {
                    colorBar = true
                    @Suppress("UNCHECKED_CAST")
                    colorBarAssemblerByTitle[scaleName] = createColorBarAssembler(
                        scaleName,
//                        transformedDomainByAes.getValue(aes),
                        ctx.overallTransformedDomain(aes),
                        scale as Scale,
                        scaleMappersNP.getValue(aes) as ScaleMapper,
                        null,
                        theme
                    )
                }

                if (!colorBar) {
//                    layerBindingsByScaleName.getOrPut(scaleName) { ArrayList() }.add(binding)
                    aesListByScaleName.getOrPut(scaleName) { ArrayList() }.add(aes)
                }
            }

            for (scaleName in aesListByScaleName.keys) {
                val legendAssembler = legendAssemblerByTitle.getOrPut(scaleName) {
                    LegendAssembler(
                        scaleName,
                        guideOptionsMap,
                        scaleMappersNP,
                        theme
                    )
                }

//                val varBindings = layerBindingsByScaleName[scaleName]!!
                val aesListForScaleName = aesListByScaleName.getValue(scaleName)
                val legendKeyFactory = contextLayer.legendKeyElementFactory
                val aestheticsDefaults = contextLayer.aestheticsDefaults
                legendAssembler.addLayer(
                    legendKeyFactory,
//                    varBindings.map { it.aes },
                    aesListForScaleName,
                    layerConstantByAes,
                    aestheticsDefaults,
//                    scaleMap,
//                    transformedDomainByAes
                    ctx
                )
            }
        }

        val legendBoxInfos = ArrayList()
        for (legendTitle in colorBarAssemblerByTitle.keys) {
            val boxInfo = colorBarAssemblerByTitle[legendTitle]!!.createColorBar()
            if (!boxInfo.isEmpty) {
                legendBoxInfos.add(boxInfo)
            }
        }

        for (legendTitle in legendAssemblerByTitle.keys) {
            val boxInfo = legendAssemblerByTitle[legendTitle]!!.createLegend()
            if (!boxInfo.isEmpty) {
                legendBoxInfos.add(boxInfo)
            }
        }
        return legendBoxInfos
    }

    fun createPlotLayout(
        layoutProviderByTile: List,
        facets: PlotFacets,
        facetsTheme: FacetsTheme,
        hAxisTheme: AxisTheme,
        vAxisTheme: AxisTheme,
    ): PlotLayout {
        if (!facets.isDefined) {
            val topDownLayout = layoutProviderByTile[0].createTopDownTileLayout()
            return SingleTilePlotLayout(topDownLayout, hAxisTheme, vAxisTheme)
        }

        return FacetedPlotLayout(
            facets,
            layoutProviderByTile,
            facetsTheme.showStrip(),
            hAxisTheme,
            vAxisTheme,
        )
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy