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

commonMain.jetbrains.datalore.plot.PlotHtmlExport.kt Maven / Gradle / Ivy

/*
 * 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

import jetbrains.datalore.base.geometry.DoubleVector
import jetbrains.datalore.plot.config.PlotConfig
import jetbrains.datalore.plot.config.PlotConfigClientSide
import kotlin.math.round

object PlotHtmlExport {
    /**
     * @param plotSpec Raw specification of a plot or GGBunch.
     * @param scriptUrl An URL to load the Lets-plot JS library from.
     * @param iFrame Whether to wrap HTML in IFrame
     * @param plotSize Desired plot size. Has no effect on GGBunch.
     */
    @Suppress("MemberVisibilityCanBePrivate")
    fun buildHtmlFromRawSpecs(
        plotSpec: MutableMap,
        scriptUrl: String,
        iFrame: Boolean = false,
        plotSize: DoubleVector? = null
    ): String {

        val configureHtml = PlotHtmlHelper.getStaticConfigureHtml(scriptUrl)
        val displayHtml = PlotHtmlHelper.getStaticDisplayHtmlForRawSpec(plotSpec, plotSize)

        val style = if (iFrame) {
            "\n       "
        } else {
            ""
        }
        val html = """
            |
            |   $style
            |       $configureHtml
            |   
            |   
            |       $displayHtml
            |   
            |
        """.trimMargin()

        return if (iFrame) {
            val attributes = ArrayList()
            attributes.add("src='about:blank'")
            attributes.add("style='border:none !important;'")
            val preferredSize = preferredPlotSizeFromRawSpec(plotSpec, plotSize)
            if (preferredSize != null) {
                attributes.add("width='${round(preferredSize.x + 0.5).toInt()}'")
                attributes.add("height='${round(preferredSize.y + 0.5).toInt()}'")
            }
            attributes.add("srcdoc=\"${escapeHtmlAttr(html)}\"")

            """
                
            """.trimIndent()
        } else {
            html
        }
    }

    private fun escapeHtmlAttr(value: String): String {
        return value
            .replace("&", "&")
            .replace("<", "<")
            .replace("\"", """)
    }

    private fun preferredPlotSizeFromRawSpec(
        plotSpec: MutableMap,
        plotSize: DoubleVector?
    ): DoubleVector? {
        try {
            @Suppress("NAME_SHADOWING")
            val plotSpec = MonolithicCommon.processRawSpecs(plotSpec, frontendOnly = false)
            if (PlotConfig.isFailure(plotSpec)) {
                return null
            }

            return when {
                PlotConfig.isPlotSpec(plotSpec) -> {
                    val config = PlotConfigClientSide.create(plotSpec) { /*ignore messages*/ }
                    PlotSizeHelper.singlePlotSize(
                        plotSpec, plotSize,
                        plotMaxWidth = null,
                        plotPreferredWidth = null,
                        config.facets, config.containsLiveMap
                    )
                }
                PlotConfig.isGGBunchSpec(plotSpec) -> {
                    PlotSizeHelper.plotBunchSize(plotSpec)
                }
                else -> null
            }
        } catch (e: RuntimeException) {
            return null
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy