Update headers and Jupyter integration

This commit is contained in:
Alexander Nozik 2021-03-10 21:58:28 +03:00
parent 1a5a207fb7
commit 97b988d419
21 changed files with 266 additions and 55 deletions

View File

@ -1,6 +1,7 @@
plugins { plugins {
id("ru.mipt.npm.gradle.project") id("ru.mipt.npm.gradle.project")
kotlin("jvm") apply false kotlin("jvm") apply false
kotlin("js") apply false
kotlin("jupyter.api") apply false kotlin("jupyter.api") apply false
} }
@ -20,7 +21,7 @@ allprojects {
} }
group = "space.kscience" group = "space.kscience"
version = "0.2.0-dev-9" version = "0.2.0-dev-13"
} }
subprojects { subprojects {

View File

@ -2,7 +2,8 @@ import ru.mipt.npm.gradle.DependencyConfiguration
import ru.mipt.npm.gradle.FXModule import ru.mipt.npm.gradle.FXModule
plugins { plugins {
id("ru.mipt.npm.gradle.mpp") kotlin("multiplatform")
id("ru.mipt.npm.gradle.common")
application application
} }

View File

@ -5,7 +5,9 @@ package drop
import org.w3c.dom.DragEvent import org.w3c.dom.DragEvent
import org.w3c.files.FileList import org.w3c.files.FileList
import react.* import react.Component
import react.RProps
import react.RState
external enum class DropEffects { external enum class DropEffects {
copy, copy,

View File

@ -22,6 +22,7 @@ private class GDMLDemoApp : Application {
val context = Global.context("demo") .apply{ val context = Global.context("demo") .apply{
plugins.fetch(ThreePlugin) plugins.fetch(ThreePlugin)
} }
render(element) { render(element) {
child(GDMLApp) { child(GDMLApp) {
val vision = GdmlShowcase.cubes.toVision() val vision = GdmlShowcase.cubes.toVision()
@ -32,7 +33,6 @@ private class GDMLDemoApp : Application {
} }
} }
} }
} }
} }

View File

@ -1,5 +1,3 @@
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
plugins { plugins {
id("ru.mipt.npm.gradle.mpp") id("ru.mipt.npm.gradle.mpp")
application application
@ -15,13 +13,14 @@ kscience {
} }
kotlin { kotlin {
jvm {
withJava()
}
afterEvaluate { afterEvaluate {
val jsBrowserDistribution by tasks.getting val jsBrowserDistribution by tasks.getting
jvm { tasks.getByName<ProcessResources>("jvmProcessResources") {
withJava()
compilations[MAIN_COMPILATION_NAME]?.apply {
tasks.getByName<ProcessResources>(processResourcesTaskName) {
dependsOn(jsBrowserDistribution) dependsOn(jsBrowserDistribution)
afterEvaluate { afterEvaluate {
from(jsBrowserDistribution) from(jsBrowserDistribution)
@ -29,9 +28,6 @@ kotlin {
} }
} }
}
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
@ -61,13 +57,13 @@ application {
mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt") mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt")
} }
distributions { //distributions {
main { // main {
contents { // contents {
from("$buildDir/libs") { // from("$buildDir/libs") {
rename("${rootProject.name}-jvm", rootProject.name) // rename("${rootProject.name}-jvm", rootProject.name)
into("lib") // into("lib")
} // }
} // }
} // }
} //}

View File

@ -1,10 +1,6 @@
package ru.mipt.npm.muon.monitor.server package ru.mipt.npm.muon.monitor.server
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Global
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.visionforge.solid.Solids
import io.ktor.application.Application import io.ktor.application.Application
import io.ktor.application.call import io.ktor.application.call
import io.ktor.application.install import io.ktor.application.install
@ -28,6 +24,10 @@ import org.apache.commons.math3.random.JDKRandomGenerator
import ru.mipt.npm.muon.monitor.Model import ru.mipt.npm.muon.monitor.Model
import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
import ru.mipt.npm.muon.monitor.sim.simulateOne import ru.mipt.npm.muon.monitor.sim.simulateOne
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.Global
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.visionforge.solid.Solids
import java.awt.Desktop import java.awt.Desktop
import java.io.File import java.io.File
import java.net.URI import java.net.URI

View File

@ -1,11 +1,11 @@
package ru.mipt.npm.muon.monitor.sim package ru.mipt.npm.muon.monitor.sim
import space.kscience.visionforge.solid.Point3D
import org.apache.commons.math3.geometry.euclidean.threed.Line import org.apache.commons.math3.geometry.euclidean.threed.Line
import org.apache.commons.math3.geometry.euclidean.threed.Plane import org.apache.commons.math3.geometry.euclidean.threed.Plane
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D import org.apache.commons.math3.geometry.euclidean.threed.Vector3D
import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z
import ru.mipt.npm.muon.monitor.Monitor.GEOMETRY_TOLERANCE import ru.mipt.npm.muon.monitor.Monitor.GEOMETRY_TOLERANCE
import space.kscience.visionforge.solid.Point3D
/** /**
* Created by darksnake on 11-May-16. * Created by darksnake on 11-May-16.

View File

@ -7,7 +7,6 @@ import ru.mipt.npm.muon.monitor.Event
import ru.mipt.npm.muon.monitor.Monitor import ru.mipt.npm.muon.monitor.Monitor
import ru.mipt.npm.muon.monitor.SC1 import ru.mipt.npm.muon.monitor.SC1
import ru.mipt.npm.muon.monitor.readResource import ru.mipt.npm.muon.monitor.readResource
import java.util.*
// minimal track length in detector // minimal track length in detector

View File

@ -1,6 +1,7 @@
package ru.mipt.npm.muon.monitor package ru.mipt.npm.muon.monitor
import kotlin.test.* import kotlin.test.Test
import kotlin.test.assertTrue
class GeometryTest { class GeometryTest {

View File

@ -27,7 +27,7 @@ public fun VisionForge.makeVisionFile(
show: Boolean = true, show: Boolean = true,
): Unit { ): Unit {
val actualPath = page(title, content = content).makeFile(path) { actualPath -> val actualPath = page(title, content = content).makeFile(path) { actualPath ->
mapOf("threeJs" to scriptHeader("js/visionforge-playground.js", actualPath, resourceLocation)) mapOf("threeJs" to scriptHeader("js/visionforge-playground.js", resourceLocation, actualPath))
} }
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
} }

View File

@ -1,16 +1,54 @@
plugins { plugins {
id("ru.mipt.npm.gradle.jvm") id("ru.mipt.npm.gradle.mpp")
kotlin("jupyter.api") kotlin("jupyter.api")
} }
description = "Jupyter api artifact for GDML rendering" description = "Jupyter api artifact for GDML rendering"
dependencies { kotlin{
explicitApi = null
js{
browser {
webpackTask {
this.outputFileName = "js/gdml-jupyter.js"
}
}
binaries.executable()
}
afterEvaluate {
val jsBrowserDistribution by tasks.getting
tasks.getByName<ProcessResources>("jvmProcessResources") {
dependsOn(jsBrowserDistribution)
afterEvaluate {
from(jsBrowserDistribution)
}
}
}
sourceSets{
commonMain {
dependencies {
api(project(":visionforge-solid"))
}
}
jvmMain{
dependencies {
implementation(project(":visionforge-gdml")) implementation(project(":visionforge-gdml"))
implementation(project(":visionforge-threejs:visionforge-threejs-server")) implementation(kotlin("script-runtime"))
}
}
jsMain {
dependencies {
api(project(":visionforge-threejs"))
implementation(project(":ui:bootstrap"))
}
}
}
} }
readme{ readme{
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
} }

View File

@ -0,0 +1,49 @@
package space.kscience.visionforge.gdml.jupyter
import org.w3c.dom.Element
import react.child
import space.kscience.dataforge.context.AbstractPlugin
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import space.kscience.visionforge.ElementVisionRenderer
import space.kscience.visionforge.Vision
import space.kscience.visionforge.solid.Solid
import space.kscience.visionforge.solid.three.ThreePlugin
import kotlin.reflect.KClass
class ThreeWithControls : AbstractPlugin(), ElementVisionRenderer {
val three by require(ThreePlugin)
override val tag: PluginTag get() = Companion.tag
override fun rateVision(vision: Vision): Int =
if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING
override fun render(element: Element, vision: Vision, meta: Meta) {
react.dom.render(element) {
child(GdmlView) {
attrs {
this.context = this@ThreeWithControls.context
this.rootVision = vision
}
}
}
}
override fun content(target: String): Map<Name, Any> {
return when (target) {
ElementVisionRenderer.TYPE -> mapOf("three.withControls".asName() to this)
else -> super.content(target)
}
}
companion object : PluginFactory<ThreeWithControls> {
override val tag: PluginTag = PluginTag("vision.threejs.withControls", PluginTag.DATAFORGE_GROUP)
override val type: KClass<ThreeWithControls> = ThreeWithControls::class
override fun invoke(meta: Meta, context: Context): ThreeWithControls = ThreeWithControls()
}
}

View File

@ -0,0 +1,32 @@
package space.kscience.visionforge.gdml.jupyter
import kotlinx.browser.window
import kotlinx.css.ListStyleType
import kotlinx.css.listStyleType
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.visionforge.VisionForge
import space.kscience.visionforge.bootstrap.useBootstrap
import space.kscience.visionforge.plugins
import styled.injectGlobal
@DFExperimental
fun main(): Unit = VisionForge.run {
useBootstrap()
injectGlobal {
rule("ul.nav") {
listStyleType = ListStyleType.none
}
rule(".treeStyles-tree") {
listStyleType = ListStyleType.none
}
rule("ol.breadcrumb") {
listStyleType = ListStyleType.none
}
}
console.info("Starting VisionForge context")
plugins.fetch(ThreeWithControls)
window.asDynamic()["VisionForge"] = VisionForge
renderVisionsInWindow()
}

View File

@ -0,0 +1,83 @@
package space.kscience.visionforge.gdml.jupyter
import kotlinx.css.*
import react.RProps
import react.child
import react.dom.h1
import react.functionalComponent
import react.useState
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.names.Name
import space.kscience.visionforge.Vision
import space.kscience.visionforge.bootstrap.gridRow
import space.kscience.visionforge.bootstrap.nameCrumbs
import space.kscience.visionforge.bootstrap.threeControls
import space.kscience.visionforge.react.ThreeCanvasComponent
import space.kscience.visionforge.react.flexColumn
import space.kscience.visionforge.solid.Solid
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
import space.kscience.visionforge.solid.three.ThreeCanvas
import styled.css
import styled.styledDiv
external interface GdmlViewProps : RProps {
var context: Context
var rootVision: Vision?
var selected: Name?
}
@JsExport
val GdmlView = functionalComponent<GdmlViewProps>("GdmlView") { props ->
var selected by useState { props.selected }
var canvas: ThreeCanvas? by useState { null }
var vision: Vision? by useState { props.rootVision }
val onSelect: (Name?) -> Unit = {
selected = it
}
gridRow {
flexColumn {
css {
+"col-lg-9"
height = 100.vh
}
styledDiv {
css {
+"mx-auto"
+"page-header"
}
h1 { +"GDML/JSON loader demo" }
}
nameCrumbs(selected, "World", onSelect)
//canvas
child(ThreeCanvasComponent) {
attrs {
this.context = props.context
this.obj = vision as? Solid
this.selected = selected
this.options = Canvas3DOptions.invoke {
this.onSelect = onSelect
}
this.canvasCallback = {
canvas = it
}
}
}
}
flexColumn {
css {
+"col-lg-3"
padding(top = 4.px)
//border(1.px, BorderStyle.solid, Color.lightGray)
height = 100.vh
overflowY = Overflow.auto
}
canvas?.let {
threeControls(it, selected, onSelect)
}
}
}
}

View File

@ -7,7 +7,8 @@ import kotlinx.html.stream.createHTML
import kotlinx.html.unsafe import kotlinx.html.unsafe
import org.jetbrains.kotlinx.jupyter.api.HTML import org.jetbrains.kotlinx.jupyter.api.HTML
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
import org.jetbrains.kotlinx.jupyter.api.libraries.* import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
import org.jetbrains.kotlinx.jupyter.api.libraries.resources
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import space.kscience.gdml.Gdml import space.kscience.gdml.Gdml
import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision
@ -25,11 +26,6 @@ import space.kscience.visionforge.visionManager
@DFExperimental @DFExperimental
internal class GdmlForJupyter : JupyterIntegration() { internal class GdmlForJupyter : JupyterIntegration() {
private val jsBundle = ResourceFallbacksBundle(listOf(
ResourceLocation("js/visionforge-three.js", ResourcePathType.CLASSPATH_PATH))
)
private val jsResource = LibraryResource(name = "visionforge-three", type = ResourceType.JS, bundles = listOf(jsBundle))
private var counter = 0 private var counter = 0
private fun produceHtmlVisionString(fragment: HtmlVisionFragment) = createHTML().div { private fun produceHtmlVisionString(fragment: HtmlVisionFragment) = createHTML().div {
@ -45,7 +41,15 @@ internal class GdmlForJupyter : JupyterIntegration() {
} }
override fun Builder.onLoaded() { override fun Builder.onLoaded() {
resource(jsResource)
resources {
js("three"){
classPath("js/gdml-jupyter.js")
}
// css("override") {
// classPath("css/jupyter-override.css")
// }
}
onLoaded { onLoaded {
VisionForge.plugins.fetch(Solids) VisionForge.plugins.fetch(Solids)

View File

@ -1,8 +1,9 @@
pluginManagement { pluginManagement {
val kotlinVersion = "1.4.31" val kotlinVersion = "1.4.31"
val toolsVersion = "0.9.1" val toolsVersion = "0.9.2"
repositories { repositories {
mavenLocal()
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
@ -15,7 +16,7 @@ pluginManagement {
id("ru.mipt.npm.gradle.js") version toolsVersion id("ru.mipt.npm.gradle.js") version toolsVersion
id("ru.mipt.npm.gradle.publish") version toolsVersion id("ru.mipt.npm.gradle.publish") version toolsVersion
kotlin("jvm") version kotlinVersion kotlin("jvm") version kotlinVersion
kotlin("jupyter.api") version "0.8.3.236" kotlin("jupyter.api") version "0.8.3.279"
kotlin("js") version kotlinVersion kotlin("js") version kotlinVersion
kotlin("multiplatform") version kotlinVersion kotlin("multiplatform") version kotlinVersion
} }

View File

@ -2,11 +2,14 @@ package space.kscience.visionforge.html
import kotlinx.html.FlowContent import kotlinx.html.FlowContent
import kotlinx.html.TagConsumer import kotlinx.html.TagConsumer
import kotlinx.html.stream.createHTML
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import space.kscience.visionforge.VisionForge import space.kscience.visionforge.VisionForge
public typealias HtmlFragment = TagConsumer<*>.() -> Unit public typealias HtmlFragment = TagConsumer<*>.() -> Unit
public fun HtmlFragment.render(): String = createHTML().apply(this).finalize()
public fun TagConsumer<*>.fragment(fragment: HtmlFragment) { public fun TagConsumer<*>.fragment(fragment: HtmlFragment) {
fragment() fragment()
} }

View File

@ -19,6 +19,7 @@ private fun whenDocumentLoaded(block: Document.() -> Unit): Unit {
@JsExport @JsExport
@DFExperimental @DFExperimental
@JsName("VisionForge")
public actual object VisionForge { public actual object VisionForge {
/** /**
* Render all visions in this [window] using current global state of [VisionForge] * Render all visions in this [window] using current global state of [VisionForge]

View File

@ -89,7 +89,7 @@ internal fun embedScriptHeader(resource: String): HtmlFragment = {
script { script {
type = "text/javascript" type = "text/javascript"
unsafe { unsafe {
val bytes = VisionManager::class.java.getResourceAsStream("/$resource").readAllBytes() val bytes = VisionManager::class.java.getResourceAsStream("/$resource")!!.readAllBytes()
+bytes.toString(Charsets.UTF_8) +bytes.toString(Charsets.UTF_8)
} }
} }
@ -113,8 +113,8 @@ internal fun fileCssHeader(
@DFExperimental @DFExperimental
public fun scriptHeader( public fun scriptHeader(
scriptResource: String, scriptResource: String,
htmlPath: Path?,
resourceLocation: ResourceLocation, resourceLocation: ResourceLocation,
htmlPath: Path? = null,
): HtmlFragment { ): HtmlFragment {
val targetPath = when (resourceLocation) { val targetPath = when (resourceLocation) {
ResourceLocation.LOCAL -> checkOrStoreFile( ResourceLocation.LOCAL -> checkOrStoreFile(

View File

@ -17,8 +17,8 @@ internal val plotlyScriptLocation = "js/visionforge-three.js"
public fun plotlyHeader(location: ResourceLocation, filePath: Path? = null): HtmlFragment = { public fun plotlyHeader(location: ResourceLocation, filePath: Path? = null): HtmlFragment = {
scriptHeader( scriptHeader(
plotlyScriptLocation, plotlyScriptLocation,
filePath, resourceLocation = location,
resourceLocation = location htmlPath = filePath
).invoke(this) ).invoke(this)
script { script {
type = "text/javascript" type = "text/javascript"

View File

@ -24,7 +24,7 @@ public fun VisionForge.makeThreeJsFile(
show: Boolean = true, show: Boolean = true,
): Unit { ): Unit {
val actualPath = page(title, content = content).makeFile(path) { actualPath -> val actualPath = page(title, content = content).makeFile(path) { actualPath ->
mapOf("threeJs" to scriptHeader("js/visionforge-three.js", actualPath, resourceLocation)) mapOf("threeJs" to scriptHeader("js/visionforge-three.js", resourceLocation, actualPath))
} }
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
} }