diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f40a4f..93e3f491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +### Security + +## [0.4.2] + +### Added +- `automargin` property to `Axis` according to https://plotly.com/python/reference/layout/xaxis/#layout-xaxis-automargin + +### Fixed +- Remove unnecessary `kotlinx-css` dependency. +- Added compatibility mode for legacy notebooks. Use `Plotly.jupyter.notebook()` call to enable legacy mode. + ### Security ## [0.4.0] ### Added diff --git a/README.md b/README.md index d7246a33..5b94a9f4 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,12 @@ ## Artifact details -**TBD** +[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/plotlykt-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22%20AND%20a:%22plotlykt-core%22) + +Dev builds and intermediate artifacts are available via `https://repo.kotlin.link` maven repository. ## Compatibility note -The current `0.4.0` version of the library is compatible with kotlin 1.4 with JS-IR and kotlinx-serialization 1.1.0. The JVM part requires JVM 11 to run. +The current `0.4.2` version of the library is compatible with kotlin 1.4 with JS-IR and kotlinx-serialization 1.1.0. The JVM part requires **JVM 11** to run. # TL;DR See [examples](./examples/src/main/kotlin). @@ -53,8 +55,8 @@ The examples of the notebooks are shown in [notebooks](./examples/notebooks) dir ```kotlin @file:Repository("https://repo.kotlin.link") -@file:DependsOn("space.kscience:plotlykt-jupyter:0.4.0") -//@file:DependsOn("space.kscience:plotlykt-server:0.4.0") // Use this one for sever integration. +@file:DependsOn("space.kscience:plotlykt-jupyter:0.4.2") +//@file:DependsOn("space.kscience:plotlykt-server:0.4.2") // Use this one for sever integration. ``` The module `plotly` allows rendering static plots in Jupyter. Jupyter lab is currently supported. Jupyter notebook (classic) is able to render only `PlotlyPage` objects, so one must convert plots to pages to be able to use notebook (see [demo notebook](./notebooks/plotlykt-demo-classic.ipynb)). @@ -90,7 +92,7 @@ repositories { } dependencies { - implementation("space.kscience:plotlykt-server:0.4.0") + implementation("space.kscience:plotlykt-server:0.4.2") } ``` diff --git a/build.gradle.kts b/build.gradle.kts index 98d8cd5d..227cc951 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ val dataforgeVersion by extra("0.4.0") allprojects { group = "space.kscience" - version = "0.4.0" + version = "0.4.2" repositories { maven("https://repo.kotlin.link") diff --git a/docs/templates/README-TEMPLATE.md b/docs/templates/README-TEMPLATE.md index 1da74c85..fe940a9b 100644 --- a/docs/templates/README-TEMPLATE.md +++ b/docs/templates/README-TEMPLATE.md @@ -7,7 +7,9 @@ ## Artifact details -**TBD** +[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/plotlykt-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22%20AND%20a:%22plotlykt-core%22) + +Dev builds and intermediate artifacts are available via `https://repo.kotlin.link` maven repository. ## Compatibility note The current `$version` version of the library is compatible with kotlin 1.4 with JS-IR and kotlinx-serialization 1.1.0. The JVM part requires JVM 11 to run. diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index b92b14af..10a0c22f 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -18,6 +18,7 @@ dependencies { tasks.withType { kotlinOptions.jvmTarget = "11" + kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn" } // A workaround for https://youtrack.jetbrains.com/issue/KT-44101 diff --git a/examples/src/main/kotlin/customPage.kt b/examples/src/main/kotlin/customPage.kt index 775ede12..7e205275 100644 --- a/examples/src/main/kotlin/customPage.kt +++ b/examples/src/main/kotlin/customPage.kt @@ -18,7 +18,7 @@ fun main() { val trace2 = Trace(x1, y2) { name = "cos" } Plotly.fragment { container -> - val plot = plot(renderer = container) { + plot(renderer = container) { traces(trace1, trace2) layout { title = "The plot above" diff --git a/fx-demo/build.gradle.kts b/fx-demo/build.gradle.kts index 0334cd57..7e60d916 100644 --- a/fx-demo/build.gradle.kts +++ b/fx-demo/build.gradle.kts @@ -15,9 +15,8 @@ repositories { } dependencies { - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - implementation("no.tornado:tornadofx:1.7.19") implementation(project(":plotlykt-server")) + implementation("no.tornado:tornadofx:1.7.19") implementation("ch.qos.logback:logback-classic:1.2.3") } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053..e708b1c0 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f371643e..0f80bbf5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fbd7c515..4f906e0c 100755 --- a/gradlew +++ b/gradlew @@ -130,7 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 5093609d..107acd32 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +64,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/js-demo/build.gradle.kts b/js-demo/build.gradle.kts index e6549a79..440646ce 100644 --- a/js-demo/build.gradle.kts +++ b/js-demo/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } repositories { - mavenLocal() + mavenCentral() jcenter() } @@ -16,5 +16,5 @@ kotlin { dependencies { implementation(project(":plotlykt-core")) - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.4.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.5.0") } \ No newline at end of file diff --git a/plotlykt-core/api/plotlykt-core.api b/plotlykt-core/api/plotlykt-core.api index e466d977..f649c1f4 100644 --- a/plotlykt-core/api/plotlykt-core.api +++ b/plotlykt-core/api/plotlykt-core.api @@ -244,6 +244,7 @@ public final class space/kscience/plotly/models/Axis : space/kscience/dataforge/ public static final field Companion Lspace/kscience/plotly/models/Axis$Companion; public fun ()V public final fun getAnchor ()Ljava/lang/String; + public final fun getAutomargin ()Ljava/lang/Boolean; public final fun getAutorange ()Z public final fun getAutotick ()Ljava/lang/Boolean; public final fun getColor ()Lspace/kscience/plotly/models/Color; @@ -273,6 +274,7 @@ public final class space/kscience/plotly/models/Axis : space/kscience/dataforge/ public final fun getZerolinecolor ()Lspace/kscience/plotly/models/Color; public final fun getZerolinewidth ()Ljava/lang/Number; public final fun setAnchor (Ljava/lang/String;)V + public final fun setAutomargin (Ljava/lang/Boolean;)V public final fun setAutorange (Z)V public final fun setAutotick (Ljava/lang/Boolean;)V public final fun setDtick (Lspace/kscience/dataforge/values/Value;)V diff --git a/plotlykt-core/build.gradle.kts b/plotlykt-core/build.gradle.kts index d4e90dd1..1e3a0c47 100644 --- a/plotlykt-core/build.gradle.kts +++ b/plotlykt-core/build.gradle.kts @@ -1,9 +1,10 @@ plugins { id("ru.mipt.npm.gradle.mpp") + `maven-publish` } kscience { - publish() + useHtml() } val dataforgeVersion: String by rootProject.extra @@ -13,8 +14,6 @@ kotlin { commonMain { dependencies { api("space.kscience:dataforge-meta:$dataforgeVersion") - api("org.jetbrains.kotlinx:kotlinx-html:${ru.mipt.npm.gradle.KScienceVersions.htmlVersion}") - api("org.jetbrains:kotlin-css:1.0.0-pre.122-kotlin-1.4.10") } } diff --git a/plotlykt-core/src/commonMain/kotlin/space/kscience/plotly/models/Axis.kt b/plotlykt-core/src/commonMain/kotlin/space/kscience/plotly/models/Axis.kt index 93b496b8..185d5bf2 100644 --- a/plotlykt-core/src/commonMain/kotlin/space/kscience/plotly/models/Axis.kt +++ b/plotlykt-core/src/commonMain/kotlin/space/kscience/plotly/models/Axis.kt @@ -221,6 +221,11 @@ public class Axis : Scheme() { public var autotick: Boolean? by boolean() + /** + * Determines whether long tick labels automatically grow the figure margins. + */ + public var automargin: Boolean? by boolean() + /** * Enumerated, one of ( "free" | "/^x([2-9]|[1-9][0-9]+)?$/" | "/^y([2-9]|[1-9][0-9]+)?$/" ) * If set to an opposite-letter axis id (e.g. `x2`, `y`), this axis is bound to the corresponding diff --git a/plotlykt-core/src/jvmMain/kotlin/space/kscience/plotly/html.kt b/plotlykt-core/src/jvmMain/kotlin/space/kscience/plotly/html.kt index 56d338e4..2a3cb60d 100644 --- a/plotlykt-core/src/jvmMain/kotlin/space/kscience/plotly/html.kt +++ b/plotlykt-core/src/jvmMain/kotlin/space/kscience/plotly/html.kt @@ -36,7 +36,7 @@ public fun Plot.toHTML( } body { StaticPlotlyRenderer.run { - renderPlot(this@toHTML, "plot", config) + renderPlot(this@toHTML, this@toHTML.toString(), config) } } } diff --git a/plotlykt-jupyter/api/plotlykt-jupyter.api b/plotlykt-jupyter/api/plotlykt-jupyter.api index e69de29b..609d7f63 100644 --- a/plotlykt-jupyter/api/plotlykt-jupyter.api +++ b/plotlykt-jupyter/api/plotlykt-jupyter.api @@ -0,0 +1,17 @@ +public final class space/kscience/plotly/PlotlyIntegration : org/jetbrains/kotlinx/jupyter/api/libraries/JupyterIntegration, space/kscience/plotly/PlotlyRenderer { + public fun ()V + public fun onLoaded (Lorg/jetbrains/kotlinx/jupyter/api/libraries/JupyterIntegration$Builder;)V + public fun renderPlot (Lkotlinx/html/FlowContent;Lspace/kscience/plotly/Plot;Ljava/lang/String;Lspace/kscience/plotly/PlotlyConfig;)Lspace/kscience/plotly/Plot; +} + +public final class space/kscience/plotly/PlotlyIntegrationKt { + public static final fun getJupyter (Lspace/kscience/plotly/Plotly;)Lspace/kscience/plotly/PlotlyJupyterConfiguration; +} + +public final class space/kscience/plotly/PlotlyJupyterConfiguration { + public static final field INSTANCE Lspace/kscience/plotly/PlotlyJupyterConfiguration; + public final fun getLegacyMode ()Z + public final fun notebook ()Lspace/kscience/plotly/PlotlyHtmlFragment; + public final fun setLegacyMode (Z)V +} + diff --git a/plotlykt-jupyter/build.gradle.kts b/plotlykt-jupyter/build.gradle.kts index 7add4afe..56fa5f8f 100644 --- a/plotlykt-jupyter/build.gradle.kts +++ b/plotlykt-jupyter/build.gradle.kts @@ -1,10 +1,7 @@ plugins { id("ru.mipt.npm.gradle.jvm") kotlin("jupyter.api") -} - -kscience{ - publish() + `maven-publish` } val dataforgeVersion: String by rootProject.extra diff --git a/plotlykt-jupyter/src/main/kotlin/space/kscience/plotly/PlotlyIntegration.kt b/plotlykt-jupyter/src/main/kotlin/space/kscience/plotly/PlotlyIntegration.kt index 07257cc1..676d1ecb 100644 --- a/plotlykt-jupyter/src/main/kotlin/space/kscience/plotly/PlotlyIntegration.kt +++ b/plotlykt-jupyter/src/main/kotlin/space/kscience/plotly/PlotlyIntegration.kt @@ -8,10 +8,33 @@ import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration import org.jetbrains.kotlinx.jupyter.api.libraries.resources import space.kscience.plotly.Plotly.PLOTLY_CDN +public object PlotlyJupyterConfiguration { + public var legacyMode: Boolean = false + + /** + * Switch plotly renderer to the legacy notebook mode (Jupyter classic) + */ + public fun notebook(): PlotlyHtmlFragment { + legacyMode = true + return PlotlyHtmlFragment { + div { + style = "color: blue;" + +"Plotly notebook integration switch into the legacy mode." + } + } + } +} + +/** + * Global plotly jupyter configuration + */ @UnstablePlotlyAPI -@JupyterLibrary -internal class PlotlyIntegration : JupyterIntegration(), PlotlyRenderer { +public val Plotly.jupyter: PlotlyJupyterConfiguration + get() = PlotlyJupyterConfiguration +@UnstablePlotlyAPI +@JupyterLibrary +public class PlotlyIntegration : JupyterIntegration(), PlotlyRenderer { override fun FlowContent.renderPlot(plot: Plot, plotId: String, config: PlotlyConfig): Plot { div { id = plotId @@ -53,11 +76,11 @@ internal class PlotlyIntegration : JupyterIntegration(), PlotlyRenderer { override fun Builder.onLoaded() { resources { - js("plotly"){ + js("plotly") { url(PLOTLY_CDN) classPath("js/plotly.min.js") } - js("plotlyConnect"){ + js("plotlyConnect") { classPath("js/plotlyConnect.js") } } @@ -71,16 +94,45 @@ internal class PlotlyIntegration : JupyterIntegration(), PlotlyRenderer { "kotlinx.html.*" ) + import("space.kscience.plotly.jupyter") + render { HTML(it.toString()) } - render { - HTML(renderPlot(it)) + val renderer = this@PlotlyIntegration + + render { plot -> + if (PlotlyJupyterConfiguration.legacyMode) { + HTML( + Plotly.page(renderer = renderer) { + plot(renderer = renderer, plot = plot) + }.render(), + true + ) + } else { + HTML( + createHTML().div { + renderer.run { renderPlot(plot) } + } + ) + } } - render { - HTML(renderFragment(it)) + render { fragment -> + if (PlotlyJupyterConfiguration.legacyMode) { + HTML( + Plotly.page(renderer = renderer) { renderer -> + fragment.render(this, renderer) + }.render(), true + ) + } else { + HTML( + createHTML().div { + fragment.render(this, renderer) + } + ) + } } render { diff --git a/plotlykt-script/build.gradle.kts b/plotlykt-script/build.gradle.kts index e3a29986..1042f23a 100644 --- a/plotlykt-script/build.gradle.kts +++ b/plotlykt-script/build.gradle.kts @@ -1,11 +1,12 @@ plugins { id("ru.mipt.npm.gradle.jvm") application + `maven-publish` } kscience{ + useHtml() application() - publish() } repositories { @@ -25,5 +26,5 @@ dependencies { } application{ - mainClassName = "space.kscience.plotly.script.CliKt" + mainClass.set("space.kscience.plotly.script.CliKt") } \ No newline at end of file diff --git a/plotlykt-server/api/plotlykt-server.api b/plotlykt-server/api/plotlykt-server.api index 8a55c1d7..2c93b990 100644 --- a/plotlykt-server/api/plotlykt-server.api +++ b/plotlykt-server/api/plotlykt-server.api @@ -31,14 +31,21 @@ public final class space/kscience/plotly/server/PlotlyServer$Companion { public final fun getUPDATE_MODE_KEY ()Lspace/kscience/dataforge/names/Name; } -public final class space/kscience/plotly/server/PlotlyServerConfig : space/kscience/dataforge/meta/Scheme { - public fun ()V +public final class space/kscience/plotly/server/PlotlyServerConfiguration : space/kscience/dataforge/meta/Scheme { + public static final field INSTANCE Lspace/kscience/plotly/server/PlotlyServerConfiguration; + public final fun getLegacyMode ()Z public final fun getPort ()I public final fun getUpdateInterval ()I + public final fun notebook ()Lspace/kscience/plotly/PlotlyHtmlFragment; + public final fun setLegacyMode (Z)V public final fun setPort (I)V public final fun setUpdateInterval (I)V } +public final class space/kscience/plotly/server/PlotlyServerIntegrationKt { + public static final fun getJupyter (Lspace/kscience/plotly/Plotly;)Lspace/kscience/plotly/server/PlotlyServerConfiguration; +} + public final class space/kscience/plotly/server/PlotlyServerKt { public static final fun close (Lio/ktor/server/engine/ApplicationEngine;)V public static final fun plotlyModule (Lio/ktor/application/Application;Ljava/lang/String;)Lspace/kscience/plotly/server/PlotlyServer; diff --git a/plotlykt-server/build.gradle.kts b/plotlykt-server/build.gradle.kts index 2ee6c0b0..f3a63e70 100644 --- a/plotlykt-server/build.gradle.kts +++ b/plotlykt-server/build.gradle.kts @@ -1,10 +1,7 @@ plugins { id("ru.mipt.npm.gradle.jvm") kotlin("jupyter.api") -} - -kscience{ - publish() + `maven-publish` } val dataforgeVersion: String by rootProject.extra @@ -12,10 +9,7 @@ val dataforgeVersion: String by rootProject.extra dependencies { api(project(":plotlykt-core")) api("io.ktor:ktor-server-cio:${ru.mipt.npm.gradle.KScienceVersions.ktorVersion}") - //api("io.ktor:ktor-server-netty:$ktorVersion") api("io.ktor:ktor-html-builder:${ru.mipt.npm.gradle.KScienceVersions.ktorVersion}") api("io.ktor:ktor-websockets:${ru.mipt.npm.gradle.KScienceVersions.ktorVersion}") - api("space.kscience:dataforge-context:$dataforgeVersion"){ - exclude(module = "kotlinx-io") - } + api("space.kscience:dataforge-context:$dataforgeVersion") } \ No newline at end of file diff --git a/plotlykt-server/src/main/kotlin/space/kscience/plotly/server/PlotlyServerIntegration.kt b/plotlykt-server/src/main/kotlin/space/kscience/plotly/server/PlotlyServerIntegration.kt index d0be70ca..1024e185 100644 --- a/plotlykt-server/src/main/kotlin/space/kscience/plotly/server/PlotlyServerIntegration.kt +++ b/plotlykt-server/src/main/kotlin/space/kscience/plotly/server/PlotlyServerIntegration.kt @@ -3,23 +3,57 @@ package space.kscience.plotly.server import io.ktor.http.URLBuilder import io.ktor.server.engine.ApplicationEngine import kotlinx.html.div +import kotlinx.html.script import kotlinx.html.stream.createHTML import kotlinx.html.style +import kotlinx.html.unsafe import org.jetbrains.kotlinx.jupyter.api.HTML import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration import org.jetbrains.kotlinx.jupyter.api.libraries.resources import org.slf4j.LoggerFactory import space.kscience.dataforge.meta.Scheme +import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.int import space.kscience.plotly.* import space.kscience.plotly.Plotly.PLOTLY_CDN -public class PlotlyServerConfig() : Scheme() { +public object PlotlyServerConfiguration : Scheme() { public var port: Int by int(System.getProperty("space.kscience.plotly.port")?.toInt() ?: 8882) public var updateInterval: Int by int(100) + + public var legacyMode: Boolean by boolean(false) + + /** + * Switch plotly renderer to the legacy notebook mode (Jupyter classic) + */ + public fun notebook(): PlotlyHtmlFragment { + legacyMode = true + return PlotlyHtmlFragment { + div { + style = "color: blue;" + +"Plotly notebook integration switch into the legacy mode." + } + } + } +} + +private val plotlyConnectHeader = PlotlyHtmlFragment { + script { + unsafe { + val bytes = PlotlyHtmlFragment::class.java.getResourceAsStream("/js/plotlyConnect.js")!!.readAllBytes() + +bytes.toString(Charsets.UTF_8) + } + } } +/** + * Global plotly jupyter configuration + */ +@UnstablePlotlyAPI +public val Plotly.jupyter: PlotlyServerConfiguration + get() = PlotlyServerConfiguration + @JupyterLibrary internal class PlotlyServerIntegration : JupyterIntegration() { private val logger = LoggerFactory.getLogger(javaClass) @@ -30,7 +64,7 @@ internal class PlotlyServerIntegration : JupyterIntegration() { private var renderer: PlotlyRenderer = StaticPlotlyRenderer - private fun start(config: PlotlyServerConfig): PlotlyHtmlFragment = if (server != null) { + private fun start(config: PlotlyServerConfiguration): PlotlyHtmlFragment = if (server != null) { PlotlyHtmlFragment { div { style = "color: blue;" @@ -58,7 +92,7 @@ internal class PlotlyServerIntegration : JupyterIntegration() { } } config.onChange(this) { name, oldItem, newItem -> - if (oldItem != newItem) { + if (name.toString() != PlotlyServerConfiguration::legacyMode.name && oldItem != newItem) { logger.info("Plotly server config parameter $name changed to $newItem") doStart() } @@ -93,34 +127,50 @@ internal class PlotlyServerIntegration : JupyterIntegration() { "kotlinx.html.*" ) - import() + import("space.kscience.plotly.server.jupyter") render { HTML(it.toString()) } - render { - HTML( - createHTML().div { - renderer.run { renderPlot(it) } - } - ) + render { plot -> + if (PlotlyServerConfiguration.legacyMode) { + HTML( + Plotly.page(cdnPlotlyHeader, plotlyConnectHeader, renderer = renderer) { + plot(renderer = renderer, plot = plot) + }.render(), true + ) + } else { + HTML( + createHTML().div { + renderer.run { renderPlot(plot) } + } + ) + } } render { fragment -> - HTML( - createHTML().div { - fragment.render(this, renderer) - } - ) + if (PlotlyServerConfiguration.legacyMode) { + HTML( + Plotly.page(cdnPlotlyHeader, plotlyConnectHeader, renderer = renderer) { renderer -> + fragment.render(this, renderer) + }.render(), true + ) + } else { + HTML( + createHTML().div { + fragment.render(this, renderer) + } + ) + } } render { page -> - HTML(page.copy(renderer = renderer).render(), true) + HTML(page.copy(headers = page.headers + plotlyConnectHeader, renderer = renderer).render(), true) } onLoaded { - val config = execute("val plotly = PlotlyServerConfig(); plotly;").value as PlotlyServerConfig + val config = PlotlyServerConfiguration logger.info("Starting JupyterPlotlyServer with $config") val serverStart = start(config) logger.info("JupyterPlotlyServer started with $config") diff --git a/settings.gradle.kts b/settings.gradle.kts index 958da7a5..64629d61 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { - val kotlinVersion = "1.5.0" - val toolsVersion = "0.9.5" + val kotlinVersion = "1.5.10" + val toolsVersion = "0.9.9" repositories { maven("https://repo.kotlin.link") @@ -15,7 +15,7 @@ pluginManagement { id("ru.mipt.npm.gradle.jvm") version toolsVersion id("ru.mipt.npm.gradle.js") version toolsVersion id("ru.mipt.npm.gradle.publish") version toolsVersion - kotlin("jupyter.api") version "0.9.1-20" + kotlin("jupyter.api") version "0.10.0-45" kotlin("jvm") version kotlinVersion kotlin("js") version kotlinVersion kotlin("multiplatform") version kotlinVersion