This commit is contained in:
Alexander Nozik 2019-06-30 14:35:54 +03:00
parent b5164916bb
commit 598030f970
38 changed files with 577 additions and 963 deletions

View File

@ -1,5 +1,13 @@
val dataforgeVersion by extra("0.1.3-dev-7") 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 { allprojects {
repositories { repositories {
mavenLocal() mavenLocal()

View File

@ -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")
}

View File

@ -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"
}

View File

@ -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<KotlinMultiplatformExtension>()?.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<PublishingExtension> {
targets.all {
val publication = publications.findByName(name) as MavenPublication
// Patch publications with fake javadoc
publication.artifact(kdocJar.get())
}
}
}
extensions.findByType<KotlinJvmProjectExtension>()?.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<PublishingExtension> {
publications.filterIsInstance<MavenPublication>().forEach { publication ->
publication.artifact(kdocJar.get())
}
}
}
}

View File

@ -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)

View File

@ -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")
}
}

View File

@ -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<MavenPublication>().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<BintrayUploadTask> {
doFirst {
publishing.publications
.filterIsInstance<MavenPublication>()
.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<PublisherConfig> {
repository(delegateClosureOf<GroovyObject> {
setProperty("repoKey", "gradle-dev-local")
setProperty("username", artifactoryUser)
setProperty("password", artifactoryPassword)
})
defaults(delegateClosureOf<GroovyObject> {
invokeMethod("publications", arrayOf("jvm", "js", "kotlinMultiplatform", "metadata"))
})
})
resolve(delegateClosureOf<ResolverConfig> {
repository(delegateClosureOf<GroovyObject> {
setProperty("repoKey", "gradle-dev")
setProperty("username", artifactoryUser)
setProperty("password", artifactoryPassword)
})
})
}

View File

@ -1,5 +1,5 @@
plugins { plugins {
`npm-multiplatform` id("scientifik.mpp")
} }
val dataforgeVersion: String by rootProject.extra val dataforgeVersion: String by rootProject.extra
@ -19,6 +19,7 @@ kotlin {
} }
val jsMain by getting { val jsMain by getting {
dependencies { dependencies {
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
// api("hep.dataforge:dataforge-output-js:$dataforgeVersion") // api("hep.dataforge:dataforge-output-js:$dataforgeVersion")
} }
} }

View File

@ -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
}

View File

@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.openjfx.gradle.JavaFXOptions import org.openjfx.gradle.JavaFXOptions
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("org.openjfx.javafxplugin") id("org.openjfx.javafxplugin")
} }

View File

@ -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<KotlinFrontendExtension> {
downloadNodeJsVersion = "latest"
configure<NpmExtension> {
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<WebPackExtension>("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"
}
}
}

View File

@ -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<MetaEditorProps, MetaEditorState>(props) {
override fun RBuilder.render() {
//this.
}
}

View File

@ -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<ColumnProps, dynamic> {
override fun render(): dynamic
companion object {
var displayName: String
}
}
external interface TreeNode {
val data: Any
val children: Array<TreeNode>?
val height: Number?
}
external class TreeState(data: Array<RowModel>) {
var data: Array<RowModel>
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<TreeNode>): TreeState
fun createEmpty(): TreeState
fun sliceRows(source: TreeState, from: Number, to: Number): Array<RowModel>
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<TreeTableProps, dynamic> {
var vListRef: Any
override fun render(): dynamic
var handleChange: Any
fun scrollTo(posY: Number): Unit
companion object {
val Column: Column
}
}

View File

@ -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<String>, callback: (updated: Array<String>) -> Unit)
fun dispose(callback: (data: dynamic) -> Unit)
}
external fun require(name: String): dynamic

View File

@ -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<String> = emptyList()
override fun start(state: Map<String, Any>) {
println("Starting application")
val element = document.getElementById("demo")!!
println("Started application")
println("${TreeTable::class} is loaded")
render(element) {
child(TreeTable::class) {
attrs {
tree<TableData> {
child(TableData("aaa", "bbb", 2))
child(TableData("ccc", "ddd", 66)) {
child(TableData("ddd", "ggg", 22))
}
}
onScroll = {}
}
column<TableData>("title"){
span { +(it.data as TableData).name }
}
column<TableData>("col1"){
span { +(it.data as TableData).col1 }
}
column<TableData>("col2"){
span { +(it.data as TableData).col2 }
}
}
}
}
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" to presenter.dispose())
}

View File

@ -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<String>
abstract fun start(state: Map<String, Any>)
abstract fun dispose(): Map<String, Any>
}
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<String, Any>())
application
} else {
null
}
}

View File

@ -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 // <CSS size> | auto
) : RProps
class TreeTableProps(
// Model properties
var value: TreeState,
var children: Array<ReactElement>,
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

View File

@ -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<D : Any>(override val data: D, override var height: Number? = null) : TreeNode {
private val _children = ArrayList<TreeNodeBuilder<D>>()
override val children: Array<TreeNode> get() = _children.toTypedArray()
fun child(data: D, block: TreeNodeBuilder<D>.() -> Unit = {}) {
val child = TreeNodeBuilder(data).apply(block)
_children.add(child)
}
}
class TreeTableBuilder<D : Any> {
private val children = ArrayList<TreeNode>()
fun child(data: D, height: Number? = null, block: TreeNodeBuilder<D>.() -> Unit = {}) {
this.children.add(TreeNodeBuilder(data, height).apply(block))
}
fun build(): TreeState = TreeState.create(children.toTypedArray())
}
fun <D : Any> TreeState.Companion.build(block: TreeTableBuilder<D>.() -> Unit): TreeState {
return TreeTableBuilder<D>().apply(block).build()
}
fun <D : Any> TreeTableProps.tree(block: TreeTableBuilder<D>.() -> Unit) {
value = TreeTableBuilder<D>().apply(block).build()
}
fun <D : Any> RElementBuilder<TreeTableProps>.column(
name: String,
renderer: (Row) -> ReactElement
): ReactElement {
val props = ColumnProps(
renderHeaderCell = { span { +name } },
renderCell = { row -> renderer.invoke(row) }
)
return createElement(TreeTable.Column, props = props)
}

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Three js demo for tree</title>
<script type="text/javascript" src="main.bundle.js"></script>
</head>
<body class="testApp">
<h1>Tree demo</h1>
<div id="demo"></div>
</body>
</html>

View File

@ -14,6 +14,7 @@ val kotlinVersion: String by rootProject.extra
dependencies { dependencies {
implementation(project(":dataforge-vis-spatial")) implementation(project(":dataforge-vis-spatial"))
//implementation("ch.viseon.threejs:wrapper:105.0.0")
implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2") implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2")
testCompile(kotlin("test-js")) testCompile(kotlin("test-js"))
} }

View File

@ -5,14 +5,15 @@ import hep.dataforge.meta.double
import hep.dataforge.meta.get import hep.dataforge.meta.get
import hep.dataforge.meta.int import hep.dataforge.meta.int
import hep.dataforge.values.ValueType import hep.dataforge.values.ValueType
import hep.dataforge.vis.common.Colors
import info.laht.threekt.materials.Material import info.laht.threekt.materials.Material
import info.laht.threekt.materials.MeshPhongMaterial import info.laht.threekt.materials.MeshPhongMaterial
import info.laht.threekt.math.Color import info.laht.threekt.math.Color
import info.laht.threekt.math.ColorConstants
object Materials { object Materials {
val DEFAULT = MeshPhongMaterial().apply { val DEFAULT = MeshPhongMaterial().apply {
this.color.set(ColorConstants.darkgreen) this.color.set(Colors.darkgreen)
} }
} }

View File

@ -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<String> = emptyList()
override fun start(state: Map<String, Any>) {
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<String>)
// }
}
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" to presenter.dispose())
}

View File

@ -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.ConvexBufferGeometry
import hep.dataforge.vis.spatial.three.EdgesGeometry import hep.dataforge.vis.spatial.three.EdgesGeometry
import hep.dataforge.vis.spatial.three.euler 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.BufferGeometry
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import info.laht.threekt.geometries.BoxBufferGeometry import info.laht.threekt.geometries.BoxBufferGeometry
@ -68,6 +69,14 @@ interface ThreeFactory<T : DisplayObject> {
} }
} }
operator fun <T : DisplayObject> ThreeFactory<T>.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<T : DisplayObject>(override val type: KClass<out T>) : ThreeFactory<T> { abstract class MeshThreeFactory<T : DisplayObject>(override val type: KClass<out T>) : ThreeFactory<T> {
/** /**
* Build an object * Build an object
@ -90,6 +99,17 @@ abstract class MeshThreeFactory<T : DisplayObject>(override val type: KClass<out
} }
} }
/**
* Generic factory for elements which provide inside geometry builder
*/
object ThreeShapeFactory : MeshThreeFactory<Shape>(Shape::class) {
override fun buildGeometry(obj: Shape): BufferGeometry {
return obj.run {
ThreeGeometryBuilder().apply { buildGeometry() }.build()
}.toBufferGeometry()
}
}
object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) { object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) {
override fun buildGeometry(obj: Box) = override fun buildGeometry(obj: Box) =
BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize)

View File

@ -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<Geometry> {
private val vertices = ArrayList<Point3D>()
private val faces = ArrayList<Face3>()
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()
}
}
}

View File

@ -11,114 +11,89 @@ import info.laht.threekt.WebGLRenderer
import info.laht.threekt.cameras.PerspectiveCamera import info.laht.threekt.cameras.PerspectiveCamera
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import info.laht.threekt.external.controls.OrbitControls import info.laht.threekt.external.controls.OrbitControls
import info.laht.threekt.helpers.AxesHelper
import info.laht.threekt.lights.AmbientLight import info.laht.threekt.lights.AmbientLight
import info.laht.threekt.math.ColorConstants import info.laht.threekt.math.ColorConstants
import info.laht.threekt.scenes.Scene import info.laht.threekt.scenes.Scene
import org.w3c.dom.Element import org.w3c.dom.Element
import kotlin.browser.window import kotlin.browser.window
import kotlin.reflect.KClass
class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : Output<DisplayObject> { class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : Output<DisplayObject> {
private val renderer = WebGLRenderer { antialias = true }.apply { private val aspectRatio by meta.number(1.0).double
setClearColor(ColorConstants.skyblue, 1)
setSize(window.innerWidth, window.innerHeight)
}
val scene: Scene = Scene().apply { val scene: Scene = Scene().apply {
add(AmbientLight()) add(AmbientLight())
if (meta["axis"] != null) {
val axesHelper = AxesHelper(meta["axis.size"].int ?: 1)
add(axesHelper)
}
} }
val camera = PerspectiveCamera( val camera = PerspectiveCamera(
meta["fov"].int ?: 75, meta["camera.fov"].int ?: 75,
window.innerWidth.toDouble() / window.innerHeight, aspectRatio,
meta["camera.nearClip"].double?: World.CAMERA_NEAR_CLIP, meta["camera.nearClip"].double ?: World.CAMERA_NEAR_CLIP,
meta["camera.farClip"].double?: World.CAMERA_FAR_CLIP meta["camera.farClip"].double ?: World.CAMERA_FAR_CLIP
).apply { ).apply {
position.setZ(World.CAMERA_INITIAL_DISTANCE) position.setZ(World.CAMERA_INITIAL_DISTANCE)
rotation.set(World.CAMERA_INITIAL_X_ANGLE, World.CAMERA_INITIAL_Y_ANGLE, World.CAMERA_INITIAL_Z_ANGLE) 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() { val height: Int = (width / aspectRatio).toInt()
window.requestAnimationFrame {
animate() 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", { 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) }, false)
element.appendChild(root)
element.replaceWith(renderer.domElement)
animate() animate()
} }
private fun buildNode(obj: DisplayObject): Object3D? { private fun buildNode(obj: DisplayObject): Object3D? {
return when (obj) { return if (obj is DisplayGroup) Group(obj.mapNotNull { buildNode(it) }).apply {
is DisplayGroup -> Group(obj.mapNotNull { buildNode(it) }).apply { ThreeFactory.updatePosition(obj, this)
ThreeFactory.updatePosition(obj, this) } else {
val factory = context.content<ThreeFactory<*>>(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 <T : DisplayObject> findFactory(type: KClass<out T>): ThreeFactory<T>? {
return context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type } as? ThreeFactory<T>?
}
override fun render(obj: DisplayObject, meta: Meta) { override fun render(obj: DisplayObject, meta: Meta) {
buildNode(obj)?.let { buildNode(obj)?.let {
scene.add(it) scene.add(it)
} ?: error("Renderer for ${obj::class} not found") } ?: error("Renderer for ${obj::class} not found")
} }
}
// init { companion object {
// val cube: Mesh fun build(context: Context, meta: Meta = EmptyMeta, override: MetaBuilder.() -> Unit) =
// ThreeOutput(context, buildMeta(meta,override))
// 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)
// }

View File

@ -13,12 +13,10 @@ class ThreePlugin : AbstractPlugin() {
val factories = HashMap<Name, ThreeFactory<*>>() val factories = HashMap<Name, ThreeFactory<*>>()
init { init {
factories["box".toName()] = ThreeBoxFactory //factories["box".toName()] = ThreeBoxFactory
factories["convex".toName()] = ThreeConvexFactory factories["convex".toName()] = ThreeConvexFactory
} }
override fun listNames(target: String): Sequence<Name> { override fun listNames(target: String): Sequence<Name> {
return when (target) { return when (target) {
ThreeFactory.TYPE -> factories.keys.asSequence() ThreeFactory.TYPE -> factories.keys.asSequence()

View File

@ -1,4 +1,4 @@
package hep.dataforge.vis package hep.dataforge.vis.spatial.demo
external val module: Module external val module: Module

View File

@ -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<String> = emptyList()
override fun start(state: Map<String, Any>) {
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<String, Any>()//mapOf("lines" to presenter.dispose())
}

View File

@ -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<Name, ThreeOutput> = 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 <T : Any> get(type: KClass<out T>, name: Name, stage: Name, meta: Meta): Output<T> {
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<T>
}
companion object : PluginFactory<ThreeDemoGrid> {
override val tag: PluginTag = PluginTag(group = "hep.dataforge", name = "vis.js.spatial.demo")
override val type: KClass<out ThreeDemoGrid> = 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>(DisplayObject::class, name.toName(), meta = meta)
output.render(action = block)
}

View File

@ -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.browser.document
import kotlin.dom.hasClass import kotlin.dom.hasClass

View File

@ -2,8 +2,8 @@ package hep.dataforge.vis.spatial.jsroot
import hep.dataforge.context.Global import hep.dataforge.context.Global
import hep.dataforge.meta.EmptyMeta import hep.dataforge.meta.EmptyMeta
import hep.dataforge.vis.ApplicationBase
import hep.dataforge.vis.spatial.ThreeOutput import hep.dataforge.vis.spatial.ThreeOutput
import hep.dataforge.vis.spatial.demo.ApplicationBase
import hep.dataforge.vis.spatial.render import hep.dataforge.vis.spatial.render
import org.w3c.dom.HTMLDivElement import org.w3c.dom.HTMLDivElement
import org.w3c.dom.events.Event import org.w3c.dom.events.Event
@ -62,7 +62,7 @@ class JSRootDemoApp : ApplicationBase() {
val renderer = ThreeOutput(Global) val renderer = ThreeOutput(Global)
val canvas = document.getElementById("canvas")!! val canvas = document.getElementById("canvas")!!
canvas.clear() canvas.clear()
renderer.start(canvas) renderer.attach(canvas)
println("started") println("started")
renderer.render { renderer.render {

View File

@ -1,29 +1,47 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Three js demo for particle physics</title> <title>Three js demo for particle physics</title>
<style> <!-- <style>-->
body { <!-- body {-->
margin: 0; <!-- margin: 0;-->
overflow: hidden; <!-- overflow: hidden;-->
} <!-- }-->
</style> <!-- </style>-->
<!--<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>--> <!--<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>-->
<!--<script type="text/javascript" src="js/OrbitControls.js"></script>--> <!--<script type="text/javascript" src="js/OrbitControls.js"></script>-->
<!--<script type="text/javascript" src="js/three.min.js"></script>--> <!--<script type="text/javascript" src="js/three.min.js"></script>-->
<!--<script type="text/javascript" src="js/ThreeCSG.js"></script>--> <!--<script type="text/javascript" src="js/ThreeCSG.js"></script>-->
<!--<script type="text/javascript" src="js/JSRootCore.js"></script>--> <!--<script type="text/javascript" src="js/JSRootCore.js"></script>-->
<!--<script type="text/javascript" src="js/JSRootGeoBase.js"></script>--> <!--<script type="text/javascript" src="js/JSRootGeoBase.js"></script>-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script type="text/javascript" src="main.bundle.js"></script> <script type="text/javascript" src="main.bundle.js"></script>
</head> </head>
<body class="testApp"> <body class="testApp">
<div id="drop_zone" data-toggle="tooltip" data-placement="right" <!--
<div class="container" id="drop_zone" data-toggle="tooltip" data-placement="right"
title="Для загрузки данных в текстовом формате, надо перетащить файл сюда"> title="Для загрузки данных в текстовом формате, надо перетащить файл сюда">
Загрузить данные Загрузить данные
<br/> <br/>
(перетащить файл сюда) (перетащить файл сюда)
</div> </div>
<h1>Demo canvas</h1> -->
<div id="canvas"></div> <div class="container">
<h1>Demo grid</h1>
</div>
<div class="container" id="canvas"></div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
</body> </body>
</html> </html>

View File

@ -1,5 +1,5 @@
plugins { plugins {
`npm-multiplatform` id("scientifik.mpp")
} }
kotlin { kotlin {

View File

@ -7,13 +7,33 @@ import hep.dataforge.vis.common.DisplayObject
import hep.dataforge.vis.common.DisplayObjectList import hep.dataforge.vis.common.DisplayObjectList
import hep.dataforge.vis.common.double 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 xSize by double(1.0)
var ySize by double(1.0) var ySize by double(1.0)
var zSize by double(1.0) var zSize by double(1.0)
//TODO add helper for color configuration //TODO add helper for color configuration
override fun <T : Any> GeometryBuilder<T>.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 { companion object {
const val TYPE = "geometry.3d.box" const val TYPE = "geometry.3d.box"
} }

View File

@ -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<Point2D>
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
}
}

View File

@ -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<Point2D>
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<T: Any> {
/**
* 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 <T: Any> GeometryBuilder<T>.buildGeometry()
}

View File

@ -3,14 +3,22 @@ pluginManagement {
jcenter() jcenter()
gradlePluginPortal() gradlePluginPortal()
maven("https://dl.bintray.com/kotlin/kotlin-eap") maven("https://dl.bintray.com/kotlin/kotlin-eap")
maven("https://dl.bintray.com/mipt-npm/scientifik")
} }
val kotlinVersion = "1.3.40"
resolutionStrategy { resolutionStrategy {
eachPlugin { eachPlugin {
when (requested.id.id) { when (requested.id.id) {
"kotlinx-atomicfu" -> useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}") "kotlinx-atomicfu" -> useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}")
"kotlin-multiplatform" -> useModule("org.jetbrains.kotlin:kotlin-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}") "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-fx",
":dataforge-vis-spatial", ":dataforge-vis-spatial",
":dataforge-vis-spatial-fx", ":dataforge-vis-spatial-fx",
":dataforge-vis-spatial-js", ":dataforge-vis-spatial-js"
":dataforge-vis-js-tree"
) )
//if(file("../dataforge-core").exists()) { //if(file("../dataforge-core").exists()) {