From 357ebb3881a11ec7789515879e1827b413518d81 Mon Sep 17 00:00:00 2001 From: Igor Alshannikov Date: Wed, 17 Apr 2024 15:59:03 -0400 Subject: [PATCH] Seed plot tools browser demo --- .../plot/browser/plotConfig/AreaBrowser.kt | 1 - .../plotConfig/PlotConfigBrowserDemoUtil.kt | 1 - .../browser/tools/PlotToolsBrowserDemoUtil.kt | 118 ++++++++++++++++++ .../plot/browser/tools/ScatterToolsBrowser.kt | 55 ++++++++ 4 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/tools/PlotToolsBrowserDemoUtil.kt create mode 100644 demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/tools/ScatterToolsBrowser.kt diff --git a/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/plotConfig/AreaBrowser.kt b/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/plotConfig/AreaBrowser.kt index 52809fd8f03..8fc62e82ecb 100644 --- a/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/plotConfig/AreaBrowser.kt +++ b/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/plotConfig/AreaBrowser.kt @@ -11,7 +11,6 @@ object AreaBrowser { @JvmStatic fun main(args: Array) { with(Area()) { - @Suppress("UNCHECKED_CAST") (PlotConfigBrowserDemoUtil.show( "Area plot", plotSpecList(), diff --git a/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/plotConfig/PlotConfigBrowserDemoUtil.kt b/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/plotConfig/PlotConfigBrowserDemoUtil.kt index 04712f9d897..d9e41c2a0e3 100644 --- a/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/plotConfig/PlotConfigBrowserDemoUtil.kt +++ b/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/plotConfig/PlotConfigBrowserDemoUtil.kt @@ -55,7 +55,6 @@ object PlotConfigBrowserDemoUtil { val plotSpecListJs = StringBuilder("[\n") - @Suppress("UNCHECKED_CAST") var first = true for (spec in plotSpecList) { @Suppress("NAME_SHADOWING") diff --git a/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/tools/PlotToolsBrowserDemoUtil.kt b/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/tools/PlotToolsBrowserDemoUtil.kt new file mode 100644 index 00000000000..604214bc49a --- /dev/null +++ b/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/tools/PlotToolsBrowserDemoUtil.kt @@ -0,0 +1,118 @@ +/* + * 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 demo.plot.browser.tools + +import demo.common.util.demoUtils.browser.BrowserDemoUtil +import kotlinx.html.* +import kotlinx.html.stream.appendHTML +import org.jetbrains.letsPlot.commons.geometry.DoubleVector +import org.jetbrains.letsPlot.core.commons.jsObject.JsObjectSupportCommon.mapToJsObjectInitializer +import org.jetbrains.letsPlot.core.spec.back.SpecTransformBackendUtil +import java.io.StringWriter + +internal object PlotToolsBrowserDemoUtil { + private const val DEMO_PROJECT = "demo/plot" + private const val ROOT_ELEMENT_ID = "root" + + fun show( + title: String, + plotSpec: MutableMap, + plotSize: DoubleVector = DoubleVector(1000.0, 600.0), + applyBackendTransform: Boolean = true, + backgroundColor: String = "lightgrey" + ) { + BrowserDemoUtil.openInBrowser(DEMO_PROJECT) { + getHtml( + title, + listOf(plotSpec), + plotSize, + applyBackendTransform, + backgroundColor + ) + } + } + + private fun getPlotLibPath(): String { + return BrowserDemoUtil.getPlotLibPath() + } + + private fun getHtml( + title: String, + plotSpecList: List>, + plotSize: DoubleVector, + applyBackendTransform: Boolean, + backgroundColor: String + ): String { + + val plotFun = if (applyBackendTransform) { // see: MonolithicJs + "buildPlotFromProcessedSpecs" + } else { + "buildPlotFromRawSpecs" + } + + val plotSpecListJs = StringBuilder("[\n") + + var first = true + for (spec in plotSpecList) { + @Suppress("NAME_SHADOWING") + val spec = if (applyBackendTransform) { + SpecTransformBackendUtil.processTransform(spec) + } else { + spec // raw: JS is going to apply transform on the client side + } + if (!first) plotSpecListJs.append(',') else first = false + plotSpecListJs.append(mapToJsObjectInitializer(spec)) + } + plotSpecListJs.append("\n]") + + val writer = StringWriter().appendHTML().html { + lang = "en" + head { + title(title) + style { + unsafe { + +""" + div.demo { + border: 1px solid orange; + margin: 20px; + display: inline-block; + } + body { + background-color:$backgroundColor + } + """.trimIndent() + } + } + } + body { + script { + type = "text/javascript" + src = getPlotLibPath() + } + + div("demo") { id = ROOT_ELEMENT_ID } + + script { + type = "text/javascript" + unsafe { + +""" + |var plotSpecList=$plotSpecListJs; + |plotSpecList.forEach(function (spec, index) { + | + | var parentElement = document.createElement('div'); + | document.getElementById("root").appendChild(parentElement); + | LetsPlot.$plotFun(spec, ${plotSize.x}, ${plotSize.y}, parentElement); + |}); + """.trimMargin() + + } + } + } + } + + return writer.toString() + } +} diff --git a/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/tools/ScatterToolsBrowser.kt b/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/tools/ScatterToolsBrowser.kt new file mode 100644 index 00000000000..b670e406e25 --- /dev/null +++ b/demo/plot/src/jvmBrowserMain/kotlin/demo/plot/browser/tools/ScatterToolsBrowser.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024. JetBrains s.r.o. + * Use of this source code is governed by the MIT license that can be found in the LICENSE file. + */ + +package demo.plot.browser.tools + +import demoAndTestShared.parsePlotSpec +import kotlin.math.PI +import kotlin.math.sin + +object ScatterToolsBrowser { + @JvmStatic + fun main(args: Array) { + with(ScatterModel()) { + (PlotToolsBrowserDemoUtil.show( + "Scatter plot tools", + plotSpec(), + )) + } + } + + @Suppress("DuplicatedCode") + private class ScatterModel { + fun plotSpec(): MutableMap { + val n = 50 + val step = 4 * PI / n + val x = List(n) { it * step } + val y = List(n) { sin(it * step) } + + val spec = """ + { + 'kind': 'plot', + 'data': { + 'x': $x, + 'y': $y + }, + 'mapping': { + 'x': 'x', + 'y': 'y', + 'color': $y + }, + 'layers': [ + { + 'geom': 'point', + 'sampling': 'none' + } + ] + } + """.trimIndent() + + return parsePlotSpec(spec) + } + } +}