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

commonMain.jetbrains.datalore.plot.builder.assemble.PlotAssembler.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.builder.assemble

import jetbrains.datalore.plot.base.Aes
import jetbrains.datalore.plot.builder.*
import jetbrains.datalore.plot.builder.coord.CoordProvider
import jetbrains.datalore.plot.builder.layout.LegendBoxInfo
import jetbrains.datalore.plot.builder.layout.LiveMapTileLayout
import jetbrains.datalore.plot.builder.layout.PlotLayout
import jetbrains.datalore.plot.builder.theme.Theme

class PlotAssembler private constructor(
    private val scaleByAes: TypedScaleMap,
    val layersByTile: List>,
    private val coordProvider: CoordProvider,
    private val theme: Theme
) {

    val containsLiveMap: Boolean = layersByTile.flatten().any(GeomLayer::isLiveMap)

    var facets: PlotFacets = PlotFacets.undefined()
    var title: String? = null
    var guideOptionsMap: Map, GuideOptions> = HashMap()

    private var legendsEnabled = true
    private var interactionsEnabled = true


    private fun hasLayers(): Boolean {
        for (tileLayers in layersByTile) {
            if (tileLayers.isNotEmpty()) {
                return true
            }
        }
        return false
    }

    fun createPlot(): PlotSvgComponent {
        require(hasLayers()) { "No layers in plot" }

        val legendsBoxInfos = when {
            legendsEnabled -> PlotAssemblerUtil.createLegends(
                layersByTile,
                guideOptionsMap,
                theme.legend()
            )
            else -> emptyList()
        }

        return if (containsLiveMap) {
            // build 'live map' plot:
            //  - skip X/Y scale training
            //  - ignore coord provider
            //  - plot layout without axes
            val plotLayout = PlotAssemblerUtil.createPlotLayout(LiveMapTileLayout(), facets, theme.facets())
            val fOrProvider = BogusFrameOfReferenceProvider()
            createPlot(fOrProvider, plotLayout, legendsBoxInfos)
        } else {
            val (xAesRange, yAesRange) = PlotAssemblerUtil.computePlotDryRunXYRanges(layersByTile)
            val fOrProvider = SquareFrameOfReferenceProvider(
                scaleByAes[Aes.X],
                scaleByAes[Aes.Y],
                xAesRange,
                yAesRange,
                coordProvider,
                theme
            )
            val plotLayout = PlotAssemblerUtil.createPlotLayout(fOrProvider.createTileLayout(), facets, theme.facets())
            createPlot(fOrProvider, plotLayout, legendsBoxInfos)
        }
    }

    private fun createPlot(
        fOrProvider: TileFrameOfReferenceProvider,
        plotLayout: PlotLayout,
        legendBoxInfos: List
    ): PlotSvgComponent {

        return PlotSvgComponent(
            title = title,
            layersByTile = layersByTile,
            plotLayout = plotLayout,
            frameOfReferenceProvider = fOrProvider,
            legendBoxInfos = legendBoxInfos,
            interactionsEnabled = interactionsEnabled,
            theme = theme
        )
    }

    fun disableLegends() {
        legendsEnabled = false
    }

    fun disableInteractions() {
        interactionsEnabled = false
    }

    companion object {
        fun singleTile(
            scaleByAes: TypedScaleMap,
            plotLayers: List,
            coordProvider: CoordProvider,
            theme: Theme
        ): PlotAssembler {
            val layersByTile = ArrayList>()
            layersByTile.add(plotLayers)
            return multiTile(
                scaleByAes,
                layersByTile,
                coordProvider,
                theme
            )
        }

        fun multiTile(
            scaleByAes: TypedScaleMap,
            layersByTile: List>,
            coordProvider: CoordProvider,
            theme: Theme
        ): PlotAssembler {
            @Suppress("NAME_SHADOWING")
            val theme = if (layersByTile.size > 1) {
                theme.multiTile()
            } else {
                theme
            }

            return PlotAssembler(
                scaleByAes,
                layersByTile,
                coordProvider,
                theme
            )
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy