diff --git a/build.gradle.kts b/build.gradle.kts index d04b42b7..7df9a46c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,13 @@ val dataforgeVersion by extra("0.1.3-dev-7") +plugins{ + kotlin("jvm") version "1.3.40" apply false + id("kotlin2js") version "1.3.40" apply false + id("kotlin-dce-js") version "1.3.40" apply false + id("org.jetbrains.kotlin.frontend") version "0.0.45" apply false + id("scientifik.mpp") version "0.1.0" apply false +} + allprojects { repositories { mavenLocal() diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts deleted file mode 100644 index 2bd41c4a..00000000 --- a/buildSrc/build.gradle.kts +++ /dev/null @@ -1,22 +0,0 @@ -plugins { - `kotlin-dsl` -} - -repositories { - gradlePluginPortal() - jcenter() - maven("https://dl.bintray.com/kotlin/kotlin-eap") -} - -val kotlinVersion = "1.3.40" - -// Add plugins used in buildSrc as dependencies, also we should specify version only here -dependencies { - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") - implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.9.6") - implementation("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4") - implementation("org.jetbrains.dokka:dokka-gradle-plugin:0.9.18") - implementation("com.moowork.gradle:gradle-node-plugin:1.3.1") - implementation("org.openjfx:javafx-plugin:0.0.7") - implementation("org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.45") -} diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts deleted file mode 100644 index e69de29b..00000000 diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt deleted file mode 100644 index 46fb0b22..00000000 --- a/buildSrc/src/main/kotlin/Versions.kt +++ /dev/null @@ -1,9 +0,0 @@ -// Instead of defining runtime properties and use them dynamically -// define version in buildSrc and have autocompletion and compile-time check -// Also dependencies itself can be moved here -object Versions { - val ioVersion = "0.1.10" - val coroutinesVersion = "1.2.1" - val atomicfuVersion = "0.12.6" - val serializationVersion = "0.11.1" -} diff --git a/buildSrc/src/main/kotlin/dokka-publish.gradle.kts b/buildSrc/src/main/kotlin/dokka-publish.gradle.kts deleted file mode 100644 index b7b48fb6..00000000 --- a/buildSrc/src/main/kotlin/dokka-publish.gradle.kts +++ /dev/null @@ -1,75 +0,0 @@ -import org.jetbrains.dokka.gradle.DokkaTask -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension - -plugins { - id("org.jetbrains.dokka") - `maven-publish` -} - -afterEvaluate { - - extensions.findByType()?.apply{ - val dokka by tasks.getting(DokkaTask::class) { - outputFormat = "html" - outputDirectory = "$buildDir/javadoc" - jdkVersion = 8 - - kotlinTasks { - // dokka fails to retrieve sources from MPP-tasks so we only define the jvm task - listOf(tasks.getByPath("compileKotlinJvm")) - } - sourceRoot { - // assuming only single source dir - path = sourceSets["commonMain"].kotlin.srcDirs.first().toString() - platforms = listOf("Common") - } - // although the JVM sources are now taken from the task, - // we still define the jvm source root to get the JVM marker in the generated html - sourceRoot { - // assuming only single source dir - path = sourceSets["jvmMain"].kotlin.srcDirs.first().toString() - platforms = listOf("JVM") - } - } - - val kdocJar by tasks.registering(Jar::class) { - group = JavaBasePlugin.DOCUMENTATION_GROUP - dependsOn(dokka) - archiveClassifier.set("javadoc") - from("$buildDir/javadoc") - } - - configure { - - targets.all { - val publication = publications.findByName(name) as MavenPublication - - // Patch publications with fake javadoc - publication.artifact(kdocJar.get()) - } - } - } - - - extensions.findByType()?.apply{ - val dokka by tasks.getting(DokkaTask::class) { - outputFormat = "html" - outputDirectory = "$buildDir/javadoc" - jdkVersion = 8 - } - - val kdocJar by tasks.registering(Jar::class) { - group = JavaBasePlugin.DOCUMENTATION_GROUP - dependsOn(dokka) - archiveClassifier.set("javadoc") - from("$buildDir/javadoc") - } - - configure { - publications.filterIsInstance().forEach { publication -> - publication.artifact(kdocJar.get()) - } - } - } -} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/js-test.gradle.kts b/buildSrc/src/main/kotlin/js-test.gradle.kts deleted file mode 100644 index 9fa69aa0..00000000 --- a/buildSrc/src/main/kotlin/js-test.gradle.kts +++ /dev/null @@ -1,43 +0,0 @@ -import com.moowork.gradle.node.npm.NpmTask -import com.moowork.gradle.node.task.NodeTask -import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile - -plugins { - id("com.moowork.node") - kotlin("multiplatform") -} - -node { - nodeModulesDir = file("$buildDir/node_modules") -} - -val compileKotlinJs by tasks.getting(Kotlin2JsCompile::class) -val compileTestKotlinJs by tasks.getting(Kotlin2JsCompile::class) - -val populateNodeModules by tasks.registering(Copy::class) { - dependsOn(compileKotlinJs) - from(compileKotlinJs.destinationDir) - - kotlin.js().compilations["test"].runtimeDependencyFiles.forEach { - if (it.exists() && !it.isDirectory) { - from(zipTree(it.absolutePath).matching { include("*.js") }) - } - } - - into("$buildDir/node_modules") -} - -val installMocha by tasks.registering(NpmTask::class) { - setWorkingDir(buildDir) - setArgs(listOf("install", "mocha")) -} - -val runMocha by tasks.registering(NodeTask::class) { - dependsOn(compileTestKotlinJs, populateNodeModules, installMocha) - setScript(file("$buildDir/node_modules/mocha/bin/mocha")) - setArgs(listOf(compileTestKotlinJs.outputFile)) -} - -tasks["jsTest"].dependsOn(runMocha) - - diff --git a/buildSrc/src/main/kotlin/npm-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/npm-multiplatform.gradle.kts deleted file mode 100644 index 20b096ab..00000000 --- a/buildSrc/src/main/kotlin/npm-multiplatform.gradle.kts +++ /dev/null @@ -1,82 +0,0 @@ -plugins { - kotlin("multiplatform") - `maven-publish` -} - - -kotlin { - jvm { - compilations.all { - kotlinOptions { - jvmTarget = "1.8" - } - } - } - - js { - compilations.all { - kotlinOptions { - metaInfo = true - sourceMap = true - sourceMapEmbedSources = "always" - moduleKind = "commonjs" - } - } - - compilations.named("main") { - kotlinOptions { - main = "call" - } - } - } - - sourceSets { - val commonMain by getting { - dependencies { - api(kotlin("stdlib")) - } - } - val commonTest by getting { - dependencies { - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) - } - } - val jvmMain by getting { - dependencies { - api(kotlin("stdlib-jdk8")) - } - } - val jvmTest by getting { - dependencies { - implementation(kotlin("test")) - implementation(kotlin("test-junit")) - } - } - val jsMain by getting { - dependencies { - api(kotlin("stdlib-js")) - } - } - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - } - - targets.all { - sourceSets.all { - languageSettings.progressiveMode = true - languageSettings.enableLanguageFeature("InlineClasses") - } - } - - // Apply JS test configuration - val runJsTests by ext(false) - - if (runJsTests) { - apply(plugin = "js-test") - } - -} diff --git a/buildSrc/src/main/kotlin/npm-publish.gradle.kts b/buildSrc/src/main/kotlin/npm-publish.gradle.kts deleted file mode 100644 index 851348ba..00000000 --- a/buildSrc/src/main/kotlin/npm-publish.gradle.kts +++ /dev/null @@ -1,136 +0,0 @@ -@file:Suppress("UnstableApiUsage") - -import com.jfrog.bintray.gradle.tasks.BintrayUploadTask -import groovy.lang.GroovyObject -import org.gradle.api.publish.maven.internal.artifact.FileBasedMavenArtifact -import org.jfrog.gradle.plugin.artifactory.dsl.PublisherConfig -import org.jfrog.gradle.plugin.artifactory.dsl.ResolverConfig - -// Old bintray.gradle script converted to real Gradle plugin (precompiled script plugin) -// It now has own dependencies and support type safe accessors -// Syntax is pretty close to what we had in Groovy -// (excluding Property.set and bintray dynamic configs) - -plugins { - `maven-publish` - id("com.jfrog.bintray") - id("com.jfrog.artifactory") -} - -val vcs = "https://github.com/altavir/dataforge-core" -val bintrayRepo = "https://bintray.com/mipt-npm/dataforge" - -// Configure publishing -publishing { - repositories { - maven(bintrayRepo) - } - - // Process each publication we have in this project - publications.filterIsInstance().forEach { publication -> - - // use type safe pom config GSL instead of old dynamic - publication.pom { - name.set(project.name) - description.set(project.description) - url.set(vcs) - - licenses { - license { - name.set("The Apache Software License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - distribution.set("repo") - } - } - developers { - developer { - id.set("MIPT-NPM") - name.set("MIPT nuclear physics methods laboratory") - organization.set("MIPT") - organizationUrl.set("http://npm.mipt.ru") - } - - } - scm { - url.set(vcs) - } - } - } - -} - -bintray { - user = findProperty("bintrayUser") as? String ?: System.getenv("BINTRAY_USER") - key = findProperty("bintrayApiKey") as? String? ?: System.getenv("BINTRAY_API_KEY") - publish = true - override = true // for multi-platform Kotlin/Native publishing - - // We have to use delegateClosureOf because bintray supports only dynamic groovy syntax - // this is a problem of this plugin - pkg.apply { - userOrg = "mipt-npm" - repo = "dataforge" - name = project.name - issueTrackerUrl = "$vcs/issues" - setLicenses("Apache-2.0") - vcsUrl = vcs - version.apply { - name = project.version.toString() - vcsTag = project.version.toString() - released = java.util.Date().toString() - } - } - - //workaround bintray bug - afterEvaluate { - setPublications(*publishing.publications.names.toTypedArray()) - } - - tasks { - bintrayUpload { - dependsOn(publishToMavenLocal) - } - } -} - -//workaround for bintray -tasks.withType { - doFirst { - publishing.publications - .filterIsInstance() - .forEach { publication -> - val moduleFile = buildDir.resolve("publications/${publication.name}/module.json") - if (moduleFile.exists()) { - publication.artifact(object : FileBasedMavenArtifact(moduleFile) { - override fun getDefaultExtension() = "module" - }) - } - } - } -} - -artifactory { - val artifactoryUser: String? by project - val artifactoryPassword: String? by project - val artifactoryContextUrl = "http://npm.mipt.ru:8081/artifactory" - - setContextUrl(artifactoryContextUrl)//The base Artifactory URL if not overridden by the publisher/resolver - publish(delegateClosureOf { - repository(delegateClosureOf { - setProperty("repoKey", "gradle-dev-local") - setProperty("username", artifactoryUser) - setProperty("password", artifactoryPassword) - }) - - defaults(delegateClosureOf { - invokeMethod("publications", arrayOf("jvm", "js", "kotlinMultiplatform", "metadata")) - }) - }) - resolve(delegateClosureOf { - repository(delegateClosureOf { - setProperty("repoKey", "gradle-dev") - setProperty("username", artifactoryUser) - setProperty("password", artifactoryPassword) - }) - }) -} diff --git a/dataforge-vis-common/build.gradle.kts b/dataforge-vis-common/build.gradle.kts index 7706865b..e0b750fb 100644 --- a/dataforge-vis-common/build.gradle.kts +++ b/dataforge-vis-common/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - `npm-multiplatform` + id("scientifik.mpp") } val dataforgeVersion: String by rootProject.extra @@ -19,6 +19,7 @@ kotlin { } val jsMain by getting { dependencies { + api("hep.dataforge:dataforge-output-html:$dataforgeVersion") // api("hep.dataforge:dataforge-output-js:$dataforgeVersion") } } diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/Colors.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/Colors.kt new file mode 100644 index 00000000..0365e300 --- /dev/null +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/Colors.kt @@ -0,0 +1,177 @@ +package hep.dataforge.vis.common + +/** + * Taken from https://github.com/markaren/three.kt/blob/master/threejs-wrapper/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt + */ +object Colors { + const val aliceblue = 0xF0F8FF + const val antiquewhite = 0xFAEBD7 + const val aqua = 0x00FFFF + const val aquamarine = 0x7FFFD4 + const val azure = 0xF0FFFF + + const val beige = 0xF5F5DC + const val bisque = 0xFFE4C4 + const val black = 0x000000 + const val blanchedalmond = 0xFFEBCD + const val blue = 0x0000FF + const val blueviolet = 0x8A2BE2 + + const val brown = 0xA52A2A + const val burlywood = 0xDEB887 + const val cadetblue = 0x5F9EA0 + const val chartreuse = 0x7FFF00 + const val chocolate = 0xD2691E + const val coral = 0xFF7F50 + + const val cornflowerblue = 0x6495ED + const val cornsilk = 0xFFF8DC + const val crimson = 0xDC143C + const val cyan = 0x00FFFF + const val darkblue = 0x00008B + const val darkcyan = 0x008B8B + + const val darkgoldenrod = 0xB8860B + const val darkgray = 0xA9A9A9 + const val darkgreen = 0x006400 + const val darkgrey = 0xA9A9A9 + const val darkkhaki = 0xBDB76B + const val darkmagenta = 0x8B008B + + const val darkolivegreen = 0x556B2F + const val darkorange = 0xFF8C00 + const val darkorchid = 0x9932CC + const val darkred = 0x8B0000 + const val darksalmon = 0xE9967A + const val darkseagreen = 0x8FBC8F + + const val darkslateblue = 0x483D8B + const val darkslategray = 0x2F4F4F + const val darkslategrey = 0x2F4F4F + const val darkturquoise = 0x00CED1 + const val darkviolet = 0x9400D3 + + const val deeppink = 0xFF1493 + const val deepskyblue = 0x00BFFF + const val dimgray = 0x696969 + const val dimgrey = 0x696969 + const val dodgerblue = 0x1E90FF + const val firebrick = 0xB22222 + + const val floralwhite = 0xFFFAF0 + const val forestgreen = 0x228B22 + const val fuchsia = 0xFF00FF + const val gainsboro = 0xDCDCDC + const val ghostwhite = 0xF8F8FF + const val gold = 0xFFD700 + + const val goldenrod = 0xDAA520 + const val gray = 0x808080 + const val green = 0x008000 + const val greenyellow = 0xADFF2F + const val grey = 0x808080 + const val honeydew = 0xF0FFF0 + const val hotpink = 0xFF69B4 + + const val indianred = 0xCD5C5C + const val indigo = 0x4B0082 + const val ivory = 0xFFFFF0 + const val khaki = 0xF0E68C + const val lavender = 0xE6E6FA + const val lavenderblush = 0xFFF0F5 + const val lawngreen = 0x7CFC00 + + const val lemonchiffon = 0xFFFACD + const val lightblue = 0xADD8E6 + const val lightcoral = 0xF08080 + const val lightcyan = 0xE0FFFF + const val lightgoldenrodyellow = 0xFAFAD2 + const val lightgray = 0xD3D3D3 + + const val lightgreen = 0x90EE90 + const val lightgrey = 0xD3D3D3 + const val lightpink = 0xFFB6C1 + const val lightsalmon = 0xFFA07A + const val lightseagreen = 0x20B2AA + const val lightskyblue = 0x87CEFA + + const val lightslategray = 0x778899 + const val lightslategrey = 0x778899 + const val lightsteelblue = 0xB0C4DE + const val lightyellow = 0xFFFFE0 + const val lime = 0x00FF00 + const val limegreen = 0x32CD32 + + const val linen = 0xFAF0E6 + const val magenta = 0xFF00FF + const val maroon = 0x800000 + const val mediumaquamarine = 0x66CDAA + const val mediumblue = 0x0000CD + const val mediumorchid = 0xBA55D3 + + const val mediumpurple = 0x9370DB + const val mediumseagreen = 0x3CB371 + const val mediumslateblue = 0x7B68EE + const val mediumspringgreen = 0x00FA9A + const val mediumturquoise = 0x48D1CC + + const val mediumvioletred = 0xC71585 + const val midnightblue = 0x191970 + const val mintcream = 0xF5FFFA + const val mistyrose = 0xFFE4E1 + const val moccasin = 0xFFE4B5 + const val navajowhite = 0xFFDEAD + + const val navy = 0x000080 + const val oldlace = 0xFDF5E6 + const val olive = 0x808000 + const val olivedrab = 0x6B8E23 + const val orange = 0xFFA500 + const val orangered = 0xFF4500 + const val orchid = 0xDA70D6 + + const val palegoldenrod = 0xEEE8AA + const val palegreen = 0x98FB98 + const val paleturquoise = 0xAFEEEE + const val palevioletred = 0xDB7093 + const val papayawhip = 0xFFEFD5 + const val peachpuff = 0xFFDAB9 + const val peru = 0xCD853F + const val pink = 0xFFC0CB + const val plum = 0xDDA0DD + const val powderblue = 0xB0E0E6 + const val purple = 0x800080 + const val rebeccapurple = 0x663399 + const val red = 0xFF0000 + const val rosybrown = 0xBC8F8F + + const val royalblue = 0x4169E1 + const val saddlebrown = 0x8B4513 + const val salmon = 0xFA8072 + const val sandybrown = 0xF4A460 + const val seagreen = 0x2E8B57 + const val seashell = 0xFFF5EE + + const val sienna = 0xA0522D + const val silver = 0xC0C0C0 + const val skyblue = 0x87CEEB + const val slateblue = 0x6A5ACD + const val slategray = 0x708090 + const val slategrey = 0x708090 + const val snow = 0xFFFAFA + + const val springgreen = 0x00FF7F + const val steelblue = 0x4682B4 + const val tan = 0xD2B48C + const val teal = 0x008080 + const val thistle = 0xD8BFD8 + const val tomato = 0xFF6347 + const val turquoise = 0x40E0D0 + + const val violet = 0xEE82EE + const val wheat = 0xF5DEB3 + const val white = 0xFFFFFF + const val whitesmoke = 0xF5F5F5 + const val yellow = 0xFFFF00 + const val yellowgreen = 0x9ACD32 +} \ No newline at end of file diff --git a/dataforge-vis-fx/build.gradle.kts b/dataforge-vis-fx/build.gradle.kts index 9383a714..ffb923c1 100644 --- a/dataforge-vis-fx/build.gradle.kts +++ b/dataforge-vis-fx/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.openjfx.gradle.JavaFXOptions plugins { - kotlin("jvm") + kotlin("jvm") id("org.openjfx.javafxplugin") } diff --git a/dataforge-vis-js-tree/build.gradle.kts b/dataforge-vis-js-tree/build.gradle.kts deleted file mode 100644 index 0fb51d83..00000000 --- a/dataforge-vis-js-tree/build.gradle.kts +++ /dev/null @@ -1,70 +0,0 @@ -import org.jetbrains.kotlin.gradle.frontend.KotlinFrontendExtension -import org.jetbrains.kotlin.gradle.frontend.npm.NpmExtension -import org.jetbrains.kotlin.gradle.frontend.webpack.WebPackExtension -import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile - -plugins { - id("kotlin2js") - id("kotlin-dce-js") - id("org.jetbrains.kotlin.frontend") -} - -repositories { - maven("https://kotlin.bintray.com/kotlin-js-wrappers") -} - -val kotlinVersion: String by rootProject.extra - -dependencies { - implementation(kotlin("stdlib-js")) - implementation(project(":dataforge-vis-common")) - implementation("org.jetbrains:kotlin-react:16.6.0-pre.73-kotlin-1.3.40") - implementation("org.jetbrains:kotlin-react-dom:16.6.0-pre.73-kotlin-1.3.40") - testCompile(kotlin("test-js")) -} - -configure { - downloadNodeJsVersion = "latest" - - configure { - dependency("core-js", "3.1.4") - dependency("cp-react-tree-table","1.0.0-beta.6") - dependency("react") - dependency("react-dom") - devDependency("karma") - } - - sourceMaps = true - - bundle("webpack") { - this as WebPackExtension - bundleName = "main" - contentPath = file("src/main/web") - sourceMapEnabled = true - //mode = "production" - mode = "development" - } -} - -tasks { - "compileKotlin2Js"(Kotlin2JsCompile::class) { - kotlinOptions { - metaInfo = true - outputFile = "${project.buildDir.path}/js/${project.name}.js" - sourceMap = true - moduleKind = "commonjs" - main = "call" - kotlinOptions.sourceMapEmbedSources = "always" - } - } - - "compileTestKotlin2Js"(Kotlin2JsCompile::class) { - kotlinOptions { - metaInfo = true - outputFile = "${project.buildDir.path}/js/${project.name}-test.js" - sourceMap = true - moduleKind = "commonjs" - kotlinOptions.sourceMapEmbedSources = "always" - } - } -} diff --git a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/MetaEditor.kt b/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/MetaEditor.kt deleted file mode 100644 index 85d8cccf..00000000 --- a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/MetaEditor.kt +++ /dev/null @@ -1,19 +0,0 @@ -package hep.dataforge.vis.js.tree - -import react.RBuilder -import react.RComponent -import react.RProps -import react.RState - -class MetaEditorState : RState { - -} - -class MetaEditorProps : RProps - -class MetaEditor(props: MetaEditorProps) : RComponent(props) { - override fun RBuilder.render() { - //this. - } - -} \ No newline at end of file diff --git a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/TreeTable.kt b/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/TreeTable.kt deleted file mode 100644 index 146b418d..00000000 --- a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/TreeTable.kt +++ /dev/null @@ -1,85 +0,0 @@ -@file:JsModule("cp-react-tree-table") -@file:JsNonModule - -package hep.dataforge.vis.js.tree - -import react.Component - -external interface RowMetadata { - var depth: Number - var index: Number - var height: Number - var hasChildren: Boolean -} - -external interface RowState { - var isVisible: Boolean - var top: Number -} - -open external class RowModel(data: RowData, metadata: RowMetadata, state: RowState) { - var data: RowData - var metadata: RowMetadata - var `$state`: RowState - - companion object { - var DEFAULT_HEIGHT: Number - } -} - -external interface RowAPI { - var toggleChildren: () -> Unit - var updateData: (newData: RowData) -> Unit -} - -external class Row(model: RowModel, api: RowAPI) : RowModel, RowAPI { - override var toggleChildren: () -> Unit - override var updateData: (newData: RowData) -> Unit -} - -external class Column : Component { - override fun render(): dynamic - - companion object { - var displayName: String - } -} - -external interface TreeNode { - val data: Any - val children: Array? - val height: Number? -} - -external class TreeState(data: Array) { - var data: Array - var height: Number - var hasData: Boolean - fun findRowModel(node: TreeNode): RowModel? - fun indexAtYPos(yPos: Number): Number - fun yPosAtIndex(index: Number): Number - - companion object { - fun create(data: Array): TreeState - fun createEmpty(): TreeState - fun sliceRows(source: TreeState, from: Number, to: Number): Array - var _hideRowsInRange: Any - var _showRowsInRange: Any - fun expandAll(source: TreeState, depthLimit: Number? = definedExternally /* null */): TreeState - fun collapseAll(source: TreeState): TreeState - fun expandAncestors(source: TreeState, model: RowModel): TreeState - fun toggleChildren(source: TreeState, model: RowModel): TreeState - fun updateData(source: TreeState, model: RowModel, newData: RowData): TreeState - } -} - -external class TreeTable : Component { - var vListRef: Any - override fun render(): dynamic - var handleChange: Any - fun scrollTo(posY: Number): Unit - - companion object { - val Column: Column - } -} \ No newline at end of file diff --git a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/demo/HMR.kt b/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/demo/HMR.kt deleted file mode 100644 index ba3dc783..00000000 --- a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/demo/HMR.kt +++ /dev/null @@ -1,19 +0,0 @@ -package hep.dataforge.vis.js.tree.demo - -external val module: Module - -external interface Module { - val hot: Hot? -} - -external interface Hot { - val data: dynamic - - fun accept() - fun accept(dependency: String, callback: () -> Unit) - fun accept(dependencies: Array, callback: (updated: Array) -> Unit) - - fun dispose(callback: (data: dynamic) -> Unit) -} - -external fun require(name: String): dynamic \ No newline at end of file diff --git a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/demo/TreeDemoApp.kt b/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/demo/TreeDemoApp.kt deleted file mode 100644 index a2805732..00000000 --- a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/demo/TreeDemoApp.kt +++ /dev/null @@ -1,54 +0,0 @@ -package hep.dataforge.vis.js.tree.demo - -import hep.dataforge.vis.js.tree.ApplicationBase -import hep.dataforge.vis.js.tree.TreeTable -import hep.dataforge.vis.js.tree.column -import hep.dataforge.vis.js.tree.tree -import react.dom.render -import react.dom.span -import kotlin.browser.document - - -data class TableData(val name: String, val col1: String, val col2: Int) - -class TreeDemoApp : ApplicationBase() { - - override val stateKeys: List = emptyList() - - override fun start(state: Map) { - - println("Starting application") - val element = document.getElementById("demo")!! - - println("Started application") - - println("${TreeTable::class} is loaded") - - - - render(element) { - child(TreeTable::class) { - attrs { - tree { - child(TableData("aaa", "bbb", 2)) - child(TableData("ccc", "ddd", 66)) { - child(TableData("ddd", "ggg", 22)) - } - } - onScroll = {} - } - column("title"){ - span { +(it.data as TableData).name } - } - column("col1"){ - span { +(it.data as TableData).col1 } - } - column("col2"){ - span { +(it.data as TableData).col2 } - } - } - } - } - - override fun dispose() = emptyMap()//mapOf("lines" to presenter.dispose()) -} \ No newline at end of file diff --git a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/main.kt b/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/main.kt deleted file mode 100644 index 5f8a0077..00000000 --- a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/main.kt +++ /dev/null @@ -1,52 +0,0 @@ -package hep.dataforge.vis.js.tree - -import hep.dataforge.vis.js.tree.demo.TreeDemoApp -import hep.dataforge.vis.js.tree.demo.module -import kotlin.browser.document -import kotlin.dom.hasClass - - -abstract class ApplicationBase { - abstract val stateKeys: List - - abstract fun start(state: Map) - abstract fun dispose(): Map -} - - -fun main() { - var application: ApplicationBase? = null - - val state: dynamic = module.hot?.let { hot -> - hot.accept() - - hot.dispose { data -> - data.appState = application?.dispose() - application = null - } - - hot.data - } - - if (document.body != null) { - application = start(state) - } else { - application = null - document.addEventListener("DOMContentLoaded", { - application = start(state) } - ) - } -} - -fun start(state: dynamic): ApplicationBase? { - return if (document.body?.hasClass("testApp") == true) { - val application = TreeDemoApp() - - @Suppress("UnsafeCastFromDynamic") - application.start(state?.appState ?: emptyMap()) - - application - } else { - null - } -} \ No newline at end of file diff --git a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/props.kt b/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/props.kt deleted file mode 100644 index 2360afe7..00000000 --- a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/props.kt +++ /dev/null @@ -1,25 +0,0 @@ -package hep.dataforge.vis.js.tree - -import react.RProps -import react.ReactElement - -class ColumnProps( - var renderCell: (row: Row) -> ReactElement, - var renderHeaderCell: () -> ReactElement, - var grow: Number? = null, - var basis: String? = null // | auto -) : RProps - -class TreeTableProps( - // Model properties - var value: TreeState, - var children: Array, - var onChange: ((TreeState) -> Unit)? = null, - // View callbacks - var onScroll: ((scrollTop: Number) -> Unit)? = null, - - // View properties - var height: Number? = null, // view height (px) - var headerHeight: Number? = null, // header height (px) - var className: String? = null -) : RProps diff --git a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/treeBuilder.kt b/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/treeBuilder.kt deleted file mode 100644 index a6b8dfec..00000000 --- a/dataforge-vis-js-tree/src/main/kotlin/hep/dataforge/vis/js/tree/treeBuilder.kt +++ /dev/null @@ -1,49 +0,0 @@ -package hep.dataforge.vis.js.tree - -import react.RElementBuilder -import react.ReactElement -import react.createElement -import react.dom.span - -typealias RowData = Any - -class TreeNodeBuilder(override val data: D, override var height: Number? = null) : TreeNode { - private val _children = ArrayList>() - override val children: Array get() = _children.toTypedArray() - - fun child(data: D, block: TreeNodeBuilder.() -> Unit = {}) { - val child = TreeNodeBuilder(data).apply(block) - _children.add(child) - } -} - - -class TreeTableBuilder { - private val children = ArrayList() - - fun child(data: D, height: Number? = null, block: TreeNodeBuilder.() -> Unit = {}) { - this.children.add(TreeNodeBuilder(data, height).apply(block)) - } - - fun build(): TreeState = TreeState.create(children.toTypedArray()) -} - -fun TreeState.Companion.build(block: TreeTableBuilder.() -> Unit): TreeState { - return TreeTableBuilder().apply(block).build() -} - -fun TreeTableProps.tree(block: TreeTableBuilder.() -> Unit) { - value = TreeTableBuilder().apply(block).build() -} - -fun RElementBuilder.column( - name: String, - renderer: (Row) -> ReactElement -): ReactElement { - val props = ColumnProps( - renderHeaderCell = { span { +name } }, - renderCell = { row -> renderer.invoke(row) } - ) - return createElement(TreeTable.Column, props = props) -} - diff --git a/dataforge-vis-js-tree/src/main/web/index.html b/dataforge-vis-js-tree/src/main/web/index.html deleted file mode 100644 index 1aa86c44..00000000 --- a/dataforge-vis-js-tree/src/main/web/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - Three js demo for tree - - - -

Tree demo

-
- - \ No newline at end of file diff --git a/dataforge-vis-spatial-js/build.gradle.kts b/dataforge-vis-spatial-js/build.gradle.kts index 54ae7e6a..9c045a7c 100644 --- a/dataforge-vis-spatial-js/build.gradle.kts +++ b/dataforge-vis-spatial-js/build.gradle.kts @@ -14,6 +14,7 @@ val kotlinVersion: String by rootProject.extra dependencies { implementation(project(":dataforge-vis-spatial")) + //implementation("ch.viseon.threejs:wrapper:105.0.0") implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2") testCompile(kotlin("test-js")) } diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/Materials.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/Materials.kt index f06744a5..3fe1073d 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/Materials.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/Materials.kt @@ -5,14 +5,15 @@ import hep.dataforge.meta.double import hep.dataforge.meta.get import hep.dataforge.meta.int import hep.dataforge.values.ValueType +import hep.dataforge.vis.common.Colors import info.laht.threekt.materials.Material import info.laht.threekt.materials.MeshPhongMaterial import info.laht.threekt.math.Color -import info.laht.threekt.math.ColorConstants + object Materials { val DEFAULT = MeshPhongMaterial().apply { - this.color.set(ColorConstants.darkgreen) + this.color.set(Colors.darkgreen) } } diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeDemoApp.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeDemoApp.kt deleted file mode 100644 index 901318fc..00000000 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeDemoApp.kt +++ /dev/null @@ -1,98 +0,0 @@ -package hep.dataforge.vis.spatial - -import hep.dataforge.context.Global -import hep.dataforge.meta.number -import hep.dataforge.vis.ApplicationBase -import hep.dataforge.vis.common.DisplayGroup -import hep.dataforge.vis.require -import hep.dataforge.vis.spatial.jsroot.JSRootPlugin -import hep.dataforge.vis.spatial.jsroot.jsRootGeometry - -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive -import kotlinx.coroutines.launch -import kotlin.browser.document -import kotlin.random.Random - - -class ThreeDemoApp : ApplicationBase() { - - override val stateKeys: List = emptyList() - - override fun start(state: Map) { - require("JSRootGeoBase.js") - - - //TODO remove after DI fix -// Global.plugins.load(ThreePlugin()) -// Global.plugins.load(JSRootPlugin()) - - Global.plugins.load(JSRootPlugin) - - val renderer = ThreeOutput(Global) - renderer.start(document.getElementById("canvas")!!) - println("started") - - lateinit var group: DisplayGroup - - renderer.render { - group = group { - box { - z = 110.0 - xSize = 100.0 - ySize = 100.0 - zSize = 100.0 - } - box { - visible = false - x = 110.0 - xSize = 100.0 - ySize = 100.0 - zSize = 100.0 - color(1530) - - GlobalScope.launch { - while (isActive) { - delay(500) - visible = !visible - } - } - } - } - convex { - point(50, 50, 50) - point(-50, -50, 50) - point(-50, 50, -50) - point(50, -50, -50) - } - jsRootGeometry { - y = 110.0 - shape = box(50, 50, 50) - color(12285) - } - } - - var color by group.properties.number(1530).int - - GlobalScope.launch { - val random = Random(111) - while (isActive) { - delay(1000) - color = random.nextInt(0, Int.MAX_VALUE) - } - } - -// view.animate() - -// view = WebLinesView(document.getElementById("lines")!!, document.getElementById("addForm")!!) -// presenter = LinesPresenter(view) -// -// state["lines"]?.let { linesState -> -// @Suppress("UNCHECKED_CAST") -// presenter.restore(linesState as Array) -// } - } - - override fun dispose() = emptyMap()//mapOf("lines" to presenter.dispose()) -} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt index 04bb7cf9..31de44dd 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt @@ -11,6 +11,7 @@ import hep.dataforge.vis.spatial.ThreeFactory.Companion.updateMesh import hep.dataforge.vis.spatial.three.ConvexBufferGeometry import hep.dataforge.vis.spatial.three.EdgesGeometry import hep.dataforge.vis.spatial.three.euler +import hep.dataforge.vis.spatial.three.toBufferGeometry import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.geometries.BoxBufferGeometry @@ -68,6 +69,14 @@ interface ThreeFactory { } } +operator fun ThreeFactory.invoke(obj: Any): Object3D { + if (type.isInstance(obj)) { + return invoke(obj as T) + } else { + error("The object of type ${obj::class} could not be rendered by this factory") + } +} + abstract class MeshThreeFactory(override val type: KClass) : ThreeFactory { /** * Build an object @@ -90,6 +99,17 @@ abstract class MeshThreeFactory(override val type: KClass(Shape::class) { + override fun buildGeometry(obj: Shape): BufferGeometry { + return obj.run { + ThreeGeometryBuilder().apply { buildGeometry() }.build() + }.toBufferGeometry() + } +} + object ThreeBoxFactory : MeshThreeFactory(Box::class) { override fun buildGeometry(obj: Box) = BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeGeometryBuilder.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeGeometryBuilder.kt new file mode 100644 index 00000000..adb75831 --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeGeometryBuilder.kt @@ -0,0 +1,47 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.meta.Meta +import hep.dataforge.meta.get +import hep.dataforge.meta.int +import info.laht.threekt.core.Face3 +import info.laht.threekt.core.Geometry +import info.laht.threekt.math.Color +import info.laht.threekt.math.Vector3 + +class ThreeGeometryBuilder : GeometryBuilder { + + private val vertices = ArrayList() + private val faces = ArrayList() + + private fun append(vertex: Point3D): Int { + val index = vertices.indexOf(vertex) + return if (index > 0) { + index + } else { + vertices.add(vertex) + vertices.size - 1 + } + } + + override fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D?, meta: Meta) { + val materialIndex = meta["materialIndex"].int ?: 0 + val color = meta["color"]?.color() ?: Color() + faces.add( + Face3( + append(vertex1), + append(vertex2), + append(vertex3), + normal?.asVector() ?: Vector3(0, 0, 0), + color, + materialIndex + ) + ) + } + + override fun build(): Geometry { + return Geometry().apply { + vertices = this@ThreeGeometryBuilder.vertices.map { it.asVector() }.toTypedArray() + faces = this@ThreeGeometryBuilder.faces.toTypedArray() + } + } +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt index a9ea2f5c..32e0d1b8 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt @@ -11,114 +11,89 @@ import info.laht.threekt.WebGLRenderer import info.laht.threekt.cameras.PerspectiveCamera import info.laht.threekt.core.Object3D import info.laht.threekt.external.controls.OrbitControls +import info.laht.threekt.helpers.AxesHelper import info.laht.threekt.lights.AmbientLight import info.laht.threekt.math.ColorConstants import info.laht.threekt.scenes.Scene import org.w3c.dom.Element import kotlin.browser.window -import kotlin.reflect.KClass class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : Output { - private val renderer = WebGLRenderer { antialias = true }.apply { - setClearColor(ColorConstants.skyblue, 1) - setSize(window.innerWidth, window.innerHeight) - } + private val aspectRatio by meta.number(1.0).double val scene: Scene = Scene().apply { add(AmbientLight()) + if (meta["axis"] != null) { + val axesHelper = AxesHelper(meta["axis.size"].int ?: 1) + add(axesHelper) + } } val camera = PerspectiveCamera( - meta["fov"].int ?: 75, - window.innerWidth.toDouble() / window.innerHeight, - meta["camera.nearClip"].double?: World.CAMERA_NEAR_CLIP, - meta["camera.farClip"].double?: World.CAMERA_FAR_CLIP + meta["camera.fov"].int ?: 75, + aspectRatio, + meta["camera.nearClip"].double ?: World.CAMERA_NEAR_CLIP, + meta["camera.farClip"].double ?: World.CAMERA_FAR_CLIP ).apply { position.setZ(World.CAMERA_INITIAL_DISTANCE) rotation.set(World.CAMERA_INITIAL_X_ANGLE, World.CAMERA_INITIAL_Y_ANGLE, World.CAMERA_INITIAL_Z_ANGLE) } - val controls: OrbitControls = OrbitControls(camera, renderer.domElement) + fun attach(element: Element, computeWidth: Element.() -> Int = { element.clientWidth }) { - val root get() = renderer.domElement + val width by meta.number(computeWidth(element)).int - private fun animate() { - window.requestAnimationFrame { - animate() + val height: Int = (width / aspectRatio).toInt() + + val renderer = WebGLRenderer { antialias = true }.apply { + setClearColor(ColorConstants.skyblue, 1) + setSize(width, height) + } + + val controls: OrbitControls = OrbitControls(camera, renderer.domElement) + + fun animate() { + window.requestAnimationFrame { + animate() + } + renderer.render(scene, camera) } - renderer.render(scene, camera) - } - fun start(element: Element) { window.addEventListener("resize", { - camera.aspect = window.innerWidth.toDouble() / window.innerHeight; - camera.updateProjectionMatrix(); + camera.updateProjectionMatrix() - renderer.setSize(window.innerWidth, window.innerHeight) + val width by meta.number(computeWidth(element)).int + + renderer.setSize(width, (width / aspectRatio).toInt()) }, false) - element.appendChild(root) + + element.replaceWith(renderer.domElement) animate() } - private fun buildNode(obj: DisplayObject): Object3D? { - return when (obj) { - is DisplayGroup -> Group(obj.mapNotNull { buildNode(it) }).apply { - ThreeFactory.updatePosition(obj, this) + return if (obj is DisplayGroup) Group(obj.mapNotNull { buildNode(it) }).apply { + ThreeFactory.updatePosition(obj, this) + } else { + val factory = context.content>(ThreeFactory.TYPE).values.find { it.type == obj::class } + when { + factory != null -> factory(obj) + obj is Shape -> ThreeShapeFactory(obj) + else -> error("Renderer for ${obj::class} not found") } - //is Box -> ThreeBoxFactory(obj) - //is JSRootObject -> ThreeJSRootFactory(obj) - //is Convex -> ThreeConvexFactory(obj) - else -> findFactory(obj::class)?.invoke(obj) ?: error("Factory not found") } } - private fun findFactory(type: KClass): ThreeFactory? { - return context.content>(ThreeFactory.TYPE).values.find { it.type == type } as? ThreeFactory? - } - override fun render(obj: DisplayObject, meta: Meta) { buildNode(obj)?.let { scene.add(it) } ?: error("Renderer for ${obj::class} not found") } -} -// init { -// val cube: Mesh -// -// cube = Mesh( -// BoxBufferGeometry(1, 1, 1), -// MeshPhongMaterial().apply { -// this.color.set(ColorConstants.darkgreen) -// } -// ).also(scene::add) -// -// Mesh(cube.geometry as BufferGeometry, -// MeshBasicMaterial().apply { -// this.wireframe = true -// this.color.set(ColorConstants.black) -// } -// ).also(cube::add) -// -// val points = CatmullRomCurve3( -// arrayOf( -// Vector3(-10, 0, 10), -// Vector3(-5, 5, 5), -// Vector3(0, 0, 0), -// Vector3(5, -5, 5), -// Vector3(10, 0, 10) -// ) -// ).getPoints(50) -// -// val geometry = BufferGeometry().setFromPoints(points) -// -// val material = LineBasicMaterial().apply { -// color.set(0xff0000) -// } -// -// // Create the final object to add to the scene -// Line(geometry, material).apply(scene::add) -// } \ No newline at end of file + companion object { + fun build(context: Context, meta: Meta = EmptyMeta, override: MetaBuilder.() -> Unit) = + ThreeOutput(context, buildMeta(meta,override)) + } +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt index 267da2d4..1f73073d 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt @@ -13,12 +13,10 @@ class ThreePlugin : AbstractPlugin() { val factories = HashMap>() init { - factories["box".toName()] = ThreeBoxFactory + //factories["box".toName()] = ThreeBoxFactory factories["convex".toName()] = ThreeConvexFactory } - - override fun listNames(target: String): Sequence { return when (target) { ThreeFactory.TYPE -> factories.keys.asSequence() diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/HMR.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/HMR.kt similarity index 80% rename from dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/HMR.kt rename to dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/HMR.kt index e65d1cf2..d5f5fffe 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/HMR.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/HMR.kt @@ -1,4 +1,4 @@ -package hep.dataforge.vis +package hep.dataforge.vis.spatial.demo external val module: Module diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt new file mode 100644 index 00000000..9a0c9253 --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt @@ -0,0 +1,77 @@ +package hep.dataforge.vis.spatial.demo + +import hep.dataforge.context.ContextBuilder +import hep.dataforge.meta.number +import hep.dataforge.vis.spatial.* +import hep.dataforge.vis.spatial.jsroot.JSRootPlugin +import hep.dataforge.vis.spatial.jsroot.jsRootGeometry +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlin.random.Random + + +class ThreeDemoApp : ApplicationBase() { + + override val stateKeys: List = emptyList() + + override fun start(state: Map) { + require("JSRootGeoBase.js") + + //TODO replace by optimized builder after dataforge 0.1.3-dev-8 + val context = ContextBuilder("three-demo").apply { + plugin(JSRootPlugin()) + }.build() + + val grid = context.plugins.load(ThreeDemoGrid()).apply { + demo("group", "Group demo") { + val group = group { + box { + z = 110.0 + xSize = 100.0 + ySize = 100.0 + zSize = 100.0 + } + box { + visible = false + x = 110.0 + xSize = 100.0 + ySize = 100.0 + zSize = 100.0 + color(1530) + + GlobalScope.launch { + while (isActive) { + delay(500) + visible = !visible + } + } + } + } + + var color by group.properties.number(1530).int + + GlobalScope.launch { + val random = Random(111) + while (isActive) { + delay(1000) + color = random.nextInt(0, Int.MAX_VALUE) + } + } + } + + demo("jsroot", "JSROOT cube"){ + jsRootGeometry { + y = 110.0 + shape = box(50, 50, 50) + color(12285) + } + } + } + + + } + + override fun dispose() = emptyMap()//mapOf("lines" to presenter.dispose()) +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt new file mode 100644 index 00000000..c6be504f --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt @@ -0,0 +1,80 @@ +package hep.dataforge.vis.spatial.demo + +import hep.dataforge.context.AbstractPlugin +import hep.dataforge.context.Context +import hep.dataforge.context.PluginFactory +import hep.dataforge.context.PluginTag +import hep.dataforge.meta.Meta +import hep.dataforge.meta.buildMeta +import hep.dataforge.meta.get +import hep.dataforge.meta.string +import hep.dataforge.names.Name +import hep.dataforge.names.toName +import hep.dataforge.output.Output +import hep.dataforge.output.OutputManager +import hep.dataforge.vis.common.DisplayObject +import hep.dataforge.vis.common.DisplayObjectList +import hep.dataforge.vis.spatial.ThreeOutput +import hep.dataforge.vis.spatial.render +import kotlinx.html.dom.append +import kotlinx.html.dom.create +import kotlinx.html.h2 +import kotlinx.html.hr +import kotlinx.html.id +import kotlinx.html.js.div +import kotlinx.html.span +import kotlin.browser.document +import kotlin.reflect.KClass + +class ThreeDemoGrid(meta: Meta) : AbstractPlugin(meta), OutputManager { + override val tag: PluginTag get() = Companion.tag + + private val gridRoot = document.create.div("row") + private val outputs: MutableMap = HashMap() + + override fun attach(context: Context) { + super.attach(context) + val elementId = meta["elementID"].string ?: "canvas" + val element = document.getElementById(elementId) ?: error("Element with id $elementId not found on page") + element.append(gridRoot) + } + + override fun get(type: KClass, name: Name, stage: Name, meta: Meta): Output { + return outputs.getOrPut(name) { + if (type != DisplayObject::class) error("Supports only DisplayObject") + val output = ThreeOutput.build(context, meta) { + "axis" to { + "size" to 500 + } + } + gridRoot.append { + span("border") { + div("col-4") { + h2 { +(meta["title"].string ?: name.toString()) } + hr() + val id = "output-$name" + output.attach(div { this.id = id }) { 300 } + } + } + } + + output + } as Output + } + + companion object : PluginFactory { + override val tag: PluginTag = PluginTag(group = "hep.dataforge", name = "vis.js.spatial.demo") + + override val type: KClass = ThreeDemoGrid::class + + override fun invoke(meta: Meta): ThreeDemoGrid = ThreeDemoGrid(meta) + } +} + +fun ThreeDemoGrid.demo(name: String, title: String = name, block: DisplayObjectList.() -> Unit) { + val meta = buildMeta { + "title" to title + } + val output = get(DisplayObject::class, name.toName(), meta = meta) + output.render(action = block) +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/main.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/main.kt similarity index 93% rename from dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/main.kt rename to dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/main.kt index 6cd9434d..9672c9ef 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/main.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/main.kt @@ -1,6 +1,5 @@ -package hep.dataforge.vis +package hep.dataforge.vis.spatial.demo -import hep.dataforge.vis.spatial.ThreeDemoApp import kotlin.browser.document import kotlin.dom.hasClass diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootDemoApp.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootDemoApp.kt index 25254c35..39575303 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootDemoApp.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootDemoApp.kt @@ -2,8 +2,8 @@ package hep.dataforge.vis.spatial.jsroot import hep.dataforge.context.Global import hep.dataforge.meta.EmptyMeta -import hep.dataforge.vis.ApplicationBase import hep.dataforge.vis.spatial.ThreeOutput +import hep.dataforge.vis.spatial.demo.ApplicationBase import hep.dataforge.vis.spatial.render import org.w3c.dom.HTMLDivElement import org.w3c.dom.events.Event @@ -62,7 +62,7 @@ class JSRootDemoApp : ApplicationBase() { val renderer = ThreeOutput(Global) val canvas = document.getElementById("canvas")!! canvas.clear() - renderer.start(canvas) + renderer.attach(canvas) println("started") renderer.render { diff --git a/dataforge-vis-spatial-js/src/main/web/index.html b/dataforge-vis-spatial-js/src/main/web/index.html index cc233d60..35a7d75b 100644 --- a/dataforge-vis-spatial-js/src/main/web/index.html +++ b/dataforge-vis-spatial-js/src/main/web/index.html @@ -1,29 +1,47 @@ + + Three js demo for particle physics - + + + + + + + -
Загрузить данные
(перетащить файл сюда)
-

Demo canvas

-
+--> +
+

Demo grid

+
+
+ + + + \ No newline at end of file diff --git a/dataforge-vis-spatial/build.gradle.kts b/dataforge-vis-spatial/build.gradle.kts index 73f33bac..29cc4387 100644 --- a/dataforge-vis-spatial/build.gradle.kts +++ b/dataforge-vis-spatial/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - `npm-multiplatform` + id("scientifik.mpp") } kotlin { diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt index 2c5aba08..dfe57903 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt @@ -7,13 +7,33 @@ import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.DisplayObjectList import hep.dataforge.vis.common.double -class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) { +class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta), Shape { var xSize by double(1.0) var ySize by double(1.0) var zSize by double(1.0) //TODO add helper for color configuration + override fun GeometryBuilder.buildGeometry() { + val dx = xSize / 2 + val dy = ySize / 2 + val dz = zSize / 2 + val node1 = Point3D(-dx, -dy, -dz) + val node2 = Point3D(dx, -dy, -dz) + val node3 = Point3D(dx, dy, -dz) + val node4 = Point3D(-dx, dy, -dz) + val node5 = Point3D(-dx, -dy, dz) + val node6 = Point3D(dx, -dy, dz) + val node7 = Point3D(dx, dy, dz) + val node8 = Point3D(-dx, dy, dz) + face4(node1, node4, node3, node2, Point3D(0, 0, -1)) + face4(node1, node2, node6, node5, Point3D(0, -1, 0)) + face4(node2, node3, node7, node6, Point3D(1, 0, 0)) + face4(node4, node8, node7, node3, Point3D(0, 1, 0)) + face4(node1, node5, node8, node4, Point3D(-1, 0, 0)) + face4(node8, node5, node6, node7, Point3D(0, 0, 1)) + } + companion object { const val TYPE = "geometry.3d.box" } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Geometry.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Geometry.kt deleted file mode 100644 index 6391b3d2..00000000 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Geometry.kt +++ /dev/null @@ -1,18 +0,0 @@ -package hep.dataforge.vis.spatial - -import hep.dataforge.meta.Meta -import hep.dataforge.meta.MetaRepr -import hep.dataforge.meta.buildMeta - - -data class Point2D(val x: Number, val y: Number) - -typealias Shape2D = List - -data class Point3D(val x: Number, val y: Number, val z: Number): MetaRepr{ - override fun toMeta(): Meta = buildMeta { - "x" to x - "y" to y - "z" to z - } -} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt new file mode 100644 index 00000000..f0b68705 --- /dev/null +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt @@ -0,0 +1,52 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.meta.EmptyMeta +import hep.dataforge.meta.Meta +import hep.dataforge.meta.MetaRepr +import hep.dataforge.meta.buildMeta +import hep.dataforge.vis.common.DisplayObject + +data class Point2D(val x: Number, val y: Number) + +typealias Shape2D = List + +data class Point3D(val x: Number, val y: Number, val z: Number) : MetaRepr { + override fun toMeta(): Meta = buildMeta { + "x" to x + "y" to y + "z" to z + } +} + +/** + * @param T the type of resulting geometry + */ +interface GeometryBuilder { + /** + * Add a face to 3D model. If one of the vertices is not present in the current geometry model list of vertices, + * it is added automatically. + * + * @param normal optional external normal to the face + * @param meta optional additional platform-specific parameters like color or texture index + */ + fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = EmptyMeta) + + fun build(): T + +} + +fun GeometryBuilder<*>.face4( + vertex1: Point3D, + vertex2: Point3D, + vertex3: Point3D, + vertex4: Point3D, + normal: Point3D? = null, + meta: Meta = EmptyMeta +) { + face(vertex1, vertex2, vertex3, normal, meta) + face(vertex1, vertex3, vertex4, normal, meta) +} + +interface Shape: DisplayObject { + fun GeometryBuilder.buildGeometry() +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 253e631d..60fd3341 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,14 +3,22 @@ pluginManagement { jcenter() gradlePluginPortal() maven("https://dl.bintray.com/kotlin/kotlin-eap") + maven("https://dl.bintray.com/mipt-npm/scientifik") } + + val kotlinVersion = "1.3.40" resolutionStrategy { eachPlugin { when (requested.id.id) { "kotlinx-atomicfu" -> useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}") "kotlin-multiplatform" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") + "org.jetbrains.kotlin.jvm" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") + "org.jetbrains.kotlin.js" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") + "kotlin-dce-js" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") "kotlin2js" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") - "org.jetbrains.kotlin.frontend" -> useModule("org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.45") + "org.jetbrains.kotlin.frontend" -> useModule("org.jetbrains.kotlin:kotlin-frontend-plugin:${requested.version}") + "scientifik.mpp", "scientifik.publish" -> useModule("scientifik:gradle-tools:${requested.version}") + "org.openjfx.javafxplugin" -> useModule("org.openjfx:javafx-plugin:${requested.version}") } } } @@ -25,8 +33,7 @@ include( ":dataforge-vis-fx", ":dataforge-vis-spatial", ":dataforge-vis-spatial-fx", - ":dataforge-vis-spatial-js", - ":dataforge-vis-js-tree" + ":dataforge-vis-spatial-js" ) //if(file("../dataforge-core").exists()) {