Use context instead of specialized plugins in JS rendering

This commit is contained in:
Alexander Nozik 2024-02-07 18:11:49 +03:00
parent 629923c03a
commit 30ad680688
32 changed files with 232 additions and 202 deletions

View File

@ -6,11 +6,11 @@ plugins {
// id("org.jetbrains.kotlinx.kover") version "0.5.0"
}
val dataforgeVersion by extra("0.7.1")
val dataforgeVersion by extra("0.8.0")
allprojects {
group = "space.kscience"
version = "0.4.0-dev-1"
version = "0.4.0-dev-2"
}
subprojects {

View File

@ -38,30 +38,6 @@ kotlin {
explicitApi = null
}
//kotlin {
//
// sourceSets {
// commonMain {
// dependencies {
// implementation(project(":visionforge-solid"))
// implementation(project(":visionforge-gdml"))
// }
// }
// jvmMain {
// dependencies {
//// implementation(project(":visionforge-fx"))
// implementation("ch.qos.logback:logback-classic:1.2.11")
// }
// }
// jsMain {
// dependencies {
// implementation(project(":ui:ring"))
// implementation(project(":visionforge-threejs"))
// implementation(npm("react-file-drop", "3.0.6"))
// }
// }
// }
//}
//val convertGdmlToJson by tasks.creating(JavaExec::class) {
// group = "application"

View File

@ -9,6 +9,7 @@ import org.jetbrains.compose.web.dom.Text
import org.w3c.files.File
import org.w3c.files.FileReader
import org.w3c.files.get
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.names.Name
import space.kscience.gdml.Gdml
import space.kscience.gdml.decodeFromString
@ -17,17 +18,18 @@ import space.kscience.visionforge.gdml.markLayers
import space.kscience.visionforge.gdml.toVision
import space.kscience.visionforge.setAsRoot
import space.kscience.visionforge.solid.Solid
import space.kscience.visionforge.solid.Solids
import space.kscience.visionforge.solid.ambientLight
import space.kscience.visionforge.solid.invoke
import space.kscience.visionforge.solid.three.compose.ThreeView
import space.kscience.visionforge.visionManager
@Composable
fun GDMLApp(solids: Solids, initialVision: Solid?, selected: Name? = null) {
fun GDMLApp(context: Context, initialVision: Solid?, selected: Name? = null) {
var vision: Solid? by remember { mutableStateOf(initialVision) }
fun readFileAsync(file: File) {
val visionManager = context.visionManager
FileReader().apply {
onload = {
val data = result as String
@ -36,7 +38,7 @@ fun GDMLApp(solids: Solids, initialVision: Solid?, selected: Name? = null) {
name.endsWith(".gdml") || name.endsWith(".xml") -> {
val gdml = Gdml.decodeFromString(data)
gdml.toVision().apply {
setAsRoot(solids.visionManager)
setAsRoot(visionManager)
console.info("Marking layers for file $name")
markLayers()
ambientLight {
@ -45,7 +47,7 @@ fun GDMLApp(solids: Solids, initialVision: Solid?, selected: Name? = null) {
}
}
name.endsWith(".json") -> solids.visionManager.decodeFromString(data)
name.endsWith(".json") -> visionManager.decodeFromString(data)
else -> {
window.alert("File extension is not recognized: $name")
error("File extension is not recognized: $name")
@ -64,7 +66,7 @@ fun GDMLApp(solids: Solids, initialVision: Solid?, selected: Name? = null) {
width(100.vw)
}
}) {
ThreeView(solids, vision, selected) {
ThreeView(context, vision, selected) {
Tab("Load") {
P {
Text("Drag and drop .gdml or .json VisionForge files here")

View File

@ -5,13 +5,11 @@ import org.jetbrains.compose.web.dom.Style
import org.jetbrains.compose.web.renderComposable
import org.w3c.dom.Document
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.request
import space.kscience.gdml.GdmlShowCase
import space.kscience.visionforge.Application
import space.kscience.visionforge.Colors
import space.kscience.visionforge.compose.TreeStyles
import space.kscience.visionforge.gdml.toVision
import space.kscience.visionforge.solid.Solids
import space.kscience.visionforge.solid.ambientLight
import space.kscience.visionforge.solid.invoke
import space.kscience.visionforge.solid.three.ThreePlugin
@ -20,11 +18,12 @@ import space.kscience.visionforge.startApplication
private class GDMLDemoApp : Application {
override fun start(document: Document, state: Map<String, Any>) {
val context = Context("gdml-demo") {
plugin(ThreePlugin)
}
override fun start(document: Document, state: Map<String, Any>) {
val element = document.getElementById("application") ?: error("Element with id 'application' not found on page")
val vision = GdmlShowCase.cubes().toVision().apply {
@ -52,7 +51,7 @@ private class GDMLDemoApp : Application {
alignItems(AlignItems.Stretch)
}
}
GDMLApp(context.request(Solids), vision)
GDMLApp(context, vision)
}
}
}

View File

@ -1,5 +1,6 @@
plugins {
id("space.kscience.gradle.mpp")
alias(spclibs.plugins.compose)
}
kscience {
@ -11,12 +12,20 @@ kotlin {
js {
browser {
binaries.executable()
commonWebpackConfig{
cssSupport{
enabled = true
}
scssSupport{
enabled = true
}
sourceMaps = true
}
}
}
}
kscience {
dependencies {
implementation(projects.visionforge.visionforgeGdml)
implementation(projects.visionforge.visionforgePlotly)

View File

@ -3,13 +3,13 @@ import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.renderComposable
import org.w3c.dom.Document
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.request
import space.kscience.plotly.models.Trace
import space.kscience.plotly.scatter
import space.kscience.visionforge.Application
import space.kscience.visionforge.Colors
import space.kscience.visionforge.JsVisionClient
import space.kscience.visionforge.compose.Tabs
import space.kscience.visionforge.compose.TreeStyles
import space.kscience.visionforge.markup.MarkupPlugin
import space.kscience.visionforge.plotly.PlotlyPlugin
import space.kscience.visionforge.solid.*
import space.kscience.visionforge.solid.three.ThreePlugin
@ -26,19 +26,21 @@ fun Trace.appendXYLatest(x: Number, y: Number, history: Int = 400, xErr: Number?
private class JsPlaygroundApp : Application {
override fun start(document: Document, state: Map<String, Any>) {
val playgroundContext = Context {
plugin(ThreePlugin)
plugin(PlotlyPlugin)
plugin(MarkupPlugin)
}
val solids = playgroundContext.request(Solids)
val client = playgroundContext.request(JsVisionClient)
override fun start(document: Document, state: Map<String, Any>) {
// val solids = playgroundContext.request(Solids)
// val client = playgroundContext.request(JsVisionClient)
val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page")
renderComposable(element) {
Style(TreeStyles)
Div({
style {
padding(0.pt)
@ -49,7 +51,7 @@ private class JsPlaygroundApp : Application {
}) {
Tabs("gravity") {
Tab("gravity") {
GravityDemo(solids, client)
GravityDemo(playgroundContext)
}
// Tab("D0") {
@ -66,7 +68,7 @@ private class JsPlaygroundApp : Application {
height(100.vh - 50.pt)
}
}) {
ThreeView(solids, SolidGroup {
ThreeView(playgroundContext, SolidGroup {
ambientLight {
color(Colors.white)
}
@ -85,7 +87,7 @@ private class JsPlaygroundApp : Application {
}
}
Tab("plotly") {
Plot(client) {
Plot(playgroundContext) {
scatter {
x(1, 2, 3)
y(5, 8, 7)

View File

@ -1,19 +1,20 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import app.softwork.bootstrapcompose.Column
import app.softwork.bootstrapcompose.Row
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.AttrBuilderContext
import org.jetbrains.compose.web.dom.Div
import org.w3c.dom.HTMLDivElement
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.meta.Meta
import space.kscience.plotly.Plot
import space.kscience.plotly.layout
import space.kscience.plotly.models.Trace
import space.kscience.visionforge.Colors
import space.kscience.visionforge.VisionClient
import space.kscience.visionforge.compose.FlexRow
import space.kscience.visionforge.compose.Vision
import space.kscience.visionforge.compose.zIndex
import space.kscience.visionforge.markup.VisionOfMarkup
@ -24,12 +25,12 @@ import kotlin.math.sqrt
@Composable
fun Plot(
client: VisionClient,
context: Context,
meta: Meta = Meta.EMPTY,
attrs: AttrBuilderContext<HTMLDivElement>? = null,
block: Plot.() -> Unit,
) = Vision(
client = client,
context = context,
attrs = attrs,
meta = meta,
vision = Plot().apply(block).asVision()
@ -37,12 +38,12 @@ fun Plot(
@Composable
fun Markup(
client: VisionClient,
context: Context,
markup: VisionOfMarkup,
meta: Meta = Meta.EMPTY,
attrs: AttrBuilderContext<HTMLDivElement>? = null,
) = Vision(
client = client,
context = context,
attrs = attrs,
meta = meta,
vision = markup
@ -52,7 +53,7 @@ fun Markup(
private val h = 100.0
@Composable
fun GravityDemo(solids: Solids, client: VisionClient) {
fun GravityDemo(context: Context) {
val velocityTrace = remember {
Trace {
name = "velocity"
@ -128,22 +129,25 @@ fun GravityDemo(solids: Solids, client: VisionClient) {
height(50.vh)
}
}) {
ThreeView(solids, solid)
ThreeView(context, solid)
}
FlexRow({
Row(attrs = {
style {
alignContent(AlignContent.Stretch)
alignItems(AlignItems.Stretch)
height(50.vh - 50.pt)
}
}) {
Plot(client) {
Column {
Plot(context) {
traces(velocityTrace, energyTrace)
layout {
xaxis.title = "time"
}
}
Markup(client, markup, attrs = {
}
Column {
Markup(context, markup, attrs = {
style {
width(100.percent)
height(100.percent)
@ -156,4 +160,5 @@ fun GravityDemo(solids: Solids, client: VisionClient) {
})
}
}
}
}

View File

@ -17,10 +17,10 @@ import org.jetbrains.compose.web.dom.P
import org.jetbrains.compose.web.dom.Span
import org.jetbrains.compose.web.dom.Text
import org.w3c.fetch.RequestInit
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.meta.invoke
import space.kscience.dataforge.names.Name
import space.kscience.visionforge.Colors
import space.kscience.visionforge.solid.Solids
import space.kscience.visionforge.solid.ambientLight
import space.kscience.visionforge.solid.edges
import space.kscience.visionforge.solid.invoke
@ -29,7 +29,7 @@ import space.kscience.visionforge.solid.three.compose.ThreeView
import kotlin.math.PI
@Composable
fun MMApp(solids: Solids, model: Model, selected: Name? = null) {
fun MMApp(context: Context, model: Model, selected: Name? = null) {
val mmOptions = remember {
Canvas3DOptions {
@ -60,7 +60,7 @@ fun MMApp(solids: Solids, model: Model, selected: Name? = null) {
}
) {
ThreeView(
solids = solids,
context,
solid = root,
initialSelected = selected,
options = mmOptions,
@ -68,7 +68,7 @@ fun MMApp(solids: Solids, model: Model, selected: Name? = null) {
Tab("Events") {
ButtonGroup({ Layout.width = Width.Full }) {
Button("Next") {
solids.context.launch {
context.launch {
val event = window.fetch(
"http://localhost:8080/event",
RequestInit("GET")

View File

@ -8,7 +8,6 @@ import space.kscience.dataforge.context.request
import space.kscience.visionforge.Application
import space.kscience.visionforge.VisionManager
import space.kscience.visionforge.compose.VisionForgeStyles
import space.kscience.visionforge.solid.Solids
import space.kscience.visionforge.solid.three.ThreePlugin
import space.kscience.visionforge.startApplication
@ -26,7 +25,7 @@ private class MMDemoApp : Application {
renderComposable("app") {
Style(VisionForgeStyles)
MMApp(context.request(Solids), model)
MMApp(context, model)
}
}
}

View File

@ -2,7 +2,6 @@ package space.kscience.visionforge.examples
import kotlinx.html.h2
import space.kscience.dataforge.meta.ValueType
import space.kscience.dataforge.meta.invoke
import space.kscience.plotly.layout
import space.kscience.plotly.models.ScatterMode
import space.kscience.plotly.models.TextPosition
@ -11,9 +10,9 @@ import space.kscience.tables.ColumnHeader
import space.kscience.visionforge.html.ResourceLocation
import space.kscience.visionforge.markup.markdown
import space.kscience.visionforge.plotly.plotly
import space.kscience.visionforge.solid.axes
import space.kscience.visionforge.solid.box
import space.kscience.visionforge.solid.solid
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
import space.kscience.visionforge.solid.z
import space.kscience.visionforge.tables.columnTable
import kotlin.io.path.Path
@ -34,14 +33,8 @@ fun main() = makeVisionFile(
h2 { +"3D visualization with Three-js" }
vision("3D") {
solid(
Canvas3DOptions {
axes {
size = 200.0
visible = true
}
}
) {
solid {
axes(200)
box(100, 100, 100, name = "aBox") {
z = 50.0
}

View File

@ -0,0 +1,19 @@
package space.kscience.visionforge.examples
import space.kscience.visionforge.html.ResourceLocation
import space.kscience.visionforge.markup.markdown
fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) {
vision {
markdown{
content = """
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
""".trimIndent()
}
}
}

View File

@ -38,10 +38,6 @@ val canvasOptions = Canvas3DOptions {
size {
minSize = 400
}
axes {
size = 500.0
visible = true
}
camera {
distance = 600.0
latitude = PI / 6
@ -52,6 +48,8 @@ val canvasOptions = Canvas3DOptions {
fun VisionLayout<Solid>.showcase() {
demo("shapes", "Basic shapes") {
ambientLight()
axes(size = 500.0)
box(100.0, 100.0, 100.0) {
z = -110.0
color("teal")

View File

@ -8,6 +8,6 @@ org.gradle.jvmargs=-Xmx4G
org.jetbrains.compose.experimental.jscanvas.enabled=true
toolsVersion=0.15.2-kotlin-1.9.21
toolsVersion=0.15.2-kotlin-1.9.22
#kotlin.experimental.tryK2=true
#kscience.wasm.disabled=true

View File

@ -63,7 +63,7 @@ private fun MetaViewerItem(root: Meta, name: Name, rootDescriptor: MetaDescripto
classes(TreeStyles.tree)
}) {
val keys = buildSet {
descriptorItem?.children?.keys?.forEach {
descriptorItem?.nodes?.keys?.forEach {
add(NameToken(it))
}
actualMeta!!.items.keys.let { addAll(it) }

View File

@ -55,7 +55,7 @@ public fun PropertyEditor(
val keys by derivedStateOf {
buildSet {
descriptor?.children?.filterNot {
descriptor?.nodes?.filterNot {
it.key.startsWith("@") || it.value.hidden
}?.forEach {
add(NameToken(it.key))

View File

@ -8,13 +8,13 @@ import kotlinx.dom.clear
import org.jetbrains.compose.web.dom.AttrBuilderContext
import org.jetbrains.compose.web.dom.Div
import org.w3c.dom.HTMLDivElement
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.gather
import space.kscience.dataforge.context.request
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import space.kscience.visionforge.ElementVisionRenderer
import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionClient
import space.kscience.visionforge.*
/**
@ -22,13 +22,20 @@ import space.kscience.visionforge.VisionClient
*/
@Composable
public fun Vision(
client: VisionClient,
context: Context,
vision: Vision,
name: Name = "@vision[${vision.hashCode().toString(16)}]".asName(),
meta: Meta = Meta.EMPTY,
attrs: AttrBuilderContext<HTMLDivElement>? = null,
): Unit = Div(attrs) {
val client: VisionClient = context.request(JsVisionClient)
// set vision root if necessary
if (vision.manager == null) {
vision.setAsRoot(client.visionManager)
}
val renderer by derivedStateOf {
client.context.gather<ElementVisionRenderer>(ElementVisionRenderer.TYPE).values.mapNotNull {
val rating = it.rateVision(vision)

View File

@ -3,7 +3,7 @@ package space.kscience.visionforge
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.meta.Scheme
import space.kscience.dataforge.meta.Specification
import space.kscience.dataforge.meta.SchemeSpec
import kotlin.properties.ReadOnlyProperty
/**
@ -36,7 +36,7 @@ public fun Vision.style(
@VisionBuilder
public fun <T : Scheme> Vision.style(
spec: Specification<T>,
spec: SchemeSpec<T>,
styleKey: String? = null,
builder: T.() -> Unit,
): ReadOnlyProperty<Any?, StyleReference> = ReadOnlyProperty { _, property ->

View File

@ -113,7 +113,7 @@ private class VisionPropertiesItem(
override val items: Map<NameToken, MutableMeta>
get() {
val metaKeys = properties.own?.get(nodeName)?.items?.keys ?: emptySet()
val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet()
val descriptorKeys = descriptor?.nodes?.map { NameToken(it.key) } ?: emptySet()
val defaultKeys = default?.get(nodeName)?.items?.keys ?: emptySet()
val inheritFlag = descriptor?.inherited ?: inherit
val stylesFlag = descriptor?.usesStyles ?: useStyles

View File

@ -55,7 +55,7 @@ public class VisionForge(
override val context: Context get() = visionManager.context
public val configuration: ObservableMutableMeta = meta.toMutableMeta()
public val configuration: ObservableMutableMeta = meta.toMutableMeta().asObservable()
private var counter = 0

View File

@ -34,7 +34,7 @@ public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer {
COMMONMARK_FORMAT -> CommonMarkFlavourDescriptor()
GFM_FORMAT -> GFMFlavourDescriptor()
//TODO add new formats via plugins
else-> error("Format ${vision.format} not recognized")
else -> error("Format ${vision.format} not recognized")
}
vision.useProperty(VisionOfMarkup::content) {
div.clear()

View File

@ -2,7 +2,7 @@ plugins {
id("space.kscience.gradle.mpp")
}
val plotlyVersion = "0.6.1"
val plotlyVersion = "0.7.0"
kscience {
jvm()

View File

@ -1,22 +1,110 @@
package space.kscience.visionforge.plotly
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.meta.Value
import space.kscience.plotly.Plotly
import space.kscience.plotly.scatter
import space.kscience.plotly.layout
import space.kscience.plotly.models.*
import space.kscience.visionforge.visionManager
import kotlin.test.Test
import kotlin.test.assertTrue
import kotlin.test.assertEquals
class VisionOfPlotlyTest {
@Test
fun conversion(){
fun conversion() {
val trace1 = Violin {
text("sample length: 32")
marker {
line {
width = 2
color("#bebada")
}
symbol = Symbol.valueOf("line-ns")
}
orientation = Orientation.h
hoveron = ViolinHoveron.`points+kde`
meanline {
visible = true
}
legendgroup = "F"
scalegroup = "F"
points = ViolinPoints.all
pointpos = 1.2
jitter = 0
box {
visible = true
}
scalemode = ViolinScaleMode.count
showlegend = false
side = ViolinSide.positive
y0 = Value.of(0)
line {
color("#bebada")
}
name = "F"
x(10.07, 34.83, 10.65, 12.43, 24.08, 13.42, 12.48, 29.8, 14.52, 11.38,
20.27, 11.17, 12.26, 18.26, 8.51, 10.33, 14.15, 13.16, 17.47, 27.05, 16.43,
8.35, 18.64, 11.87, 19.81, 43.11, 13.0, 12.74, 13.0, 16.4, 16.47, 18.78)
}
val trace2 = Violin {
text("sample length: 30")
marker {
line {
width = 2
color("#8dd3c7")
}
symbol = Symbol.valueOf("line-ns")
}
orientation = Orientation.h
hoveron = ViolinHoveron.`points+kde`
meanline {
visible = true
}
legendgroup = "M"
scalegroup = "M"
points = ViolinPoints.all
pointpos = -1.2
jitter = 0
box {
visible = true
}
scalemode = ViolinScaleMode.count
showlegend = false
side = ViolinSide.negative
y0 = Value.of(0)
line {
color("#8dd3c7")
}
name = "M"
x(27.2, 22.76, 17.29, 19.44, 16.66, 32.68, 15.98, 13.03, 18.28, 24.71,
21.16, 11.69, 14.26, 15.95, 8.52, 22.82, 19.08, 16.0, 34.3, 41.19, 9.78,
7.51, 28.44, 15.48, 16.58, 7.56, 10.34, 13.51, 18.71, 20.53)
}
val plot = Plotly.plot {
scatter {
x(1,2,3)
y(1,2,3)
traces(trace1, trace2)
layout {
width = 800
height = 800
title = "Advanced Violin Plot"
}
}
val vision = VisionOfPlotly(plot)
// println(vision.plot.toJsonString())
// println(vision.plot.data.toJsonString())
assertTrue { vision.plot.data.first().x.doubles.size == 3}
val context = Context {
plugin(PlotlyPlugin)
}
val serialized = context.visionManager.encodeToString(vision)
val deserialized: VisionOfPlotly = context.visionManager.decodeFromString(serialized) as VisionOfPlotly
println(deserialized.plot.meta)
assertEquals(62, deserialized.plot.data.sumOf { it.x.doubles.size})
assertEquals("Advanced Violin Plot", deserialized.plot.layout.title)
}
}

View File

@ -1,35 +0,0 @@
package space.kscience.visionforge.solid.specifications
import space.kscience.dataforge.meta.Scheme
import space.kscience.dataforge.meta.SchemeSpec
import space.kscience.dataforge.meta.boolean
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.meta.descriptors.value
import space.kscience.dataforge.meta.double
@Deprecated("Use separate axes object instead")
public class AxesScheme : Scheme() {
public var visible: Boolean by boolean(false)
public var size: Double by double(AXIS_SIZE)
public var width: Double by double(AXIS_WIDTH)
@Suppress("DEPRECATION")
public companion object : SchemeSpec<AxesScheme>(::AxesScheme) {
public const val AXIS_SIZE: Double = 1000.0
public const val AXIS_WIDTH: Double = 3.0
override val descriptor: MetaDescriptor by lazy {
MetaDescriptor {
value(AxesScheme::visible){
default(false)
}
value(AxesScheme::size){
default(AXIS_SIZE)
}
value(AxesScheme::width){
default(AXIS_WIDTH)
}
}
}
}
}

View File

@ -1,3 +1,5 @@
@file:OptIn(DFExperimental::class)
package space.kscience.visionforge.solid.specifications
import space.kscience.dataforge.meta.*
@ -5,6 +7,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.meta.descriptors.scheme
import space.kscience.dataforge.meta.descriptors.value
import space.kscience.dataforge.meta.set
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.visionforge.hide
import space.kscience.visionforge.widgetType
@ -61,16 +64,14 @@ public class CanvasSize : Scheme() {
public class Canvas3DOptions : Scheme() {
public var canvasName: String by string("vision")
@Suppress("DEPRECATION")
public var axes: AxesScheme by spec(AxesScheme)
public var camera: CameraScheme by spec(CameraScheme)
public var controls: Canvas3DUIScheme by spec(Canvas3DUIScheme)
public var camera: CameraScheme by scheme(CameraScheme)
public var controls: Canvas3DUIScheme by scheme(Canvas3DUIScheme)
public var size: CanvasSize by spec(CanvasSize)
public var size: CanvasSize by scheme(CanvasSize)
public var layers: List<Number> by numberList(0)
public var clipping: PointScheme by spec(Clipping)
public var clipping: PointScheme by scheme(Clipping)
public var onSelect: ((Name?) -> Unit)? = null
@ -78,9 +79,6 @@ public class Canvas3DOptions : Scheme() {
public companion object : SchemeSpec<Canvas3DOptions>(::Canvas3DOptions) {
override val descriptor: MetaDescriptor by lazy {
MetaDescriptor {
@Suppress("DEPRECATION")
scheme(Canvas3DOptions::axes, AxesScheme)
value(Canvas3DOptions::layers) {
multiple = true
default(listOf(0))

View File

@ -1,21 +0,0 @@
package space.kscience.visionforge.solid
import space.kscience.dataforge.meta.ValueType
import space.kscience.dataforge.meta.descriptors.get
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
import kotlin.test.Test
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
class DescriptorTest {
@Test
fun canvasDescriptor() {
val descriptor = Canvas3DOptions.descriptor
//println(descriptor.config)
val axesSize = descriptor["axes.size"]
assertNotNull(axesSize)
assertTrue {
ValueType.NUMBER in axesSize.valueTypes!!
}
}
}

View File

@ -2,7 +2,7 @@ plugins {
id("space.kscience.gradle.mpp")
}
val tablesVersion = "0.3.0"
val tablesVersion = "0.4.0"
kscience {
jvm()

View File

@ -70,7 +70,7 @@ public fun <T> Table<T>.toVision(
} else {
Meta {
headers.forEach {
it.name put converter(row[it.name])
it.name put converter(row.getOrNull(it.name))
}
}
}

View File

@ -1,6 +1,6 @@
package space.kscience.visionforge.tables
import js.core.jso
import js.objects.jso
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
import space.kscience.dataforge.context.AbstractPlugin

View File

@ -20,7 +20,6 @@ import three.core.Raycaster
import three.external.controls.OrbitControls
import three.external.controls.TrackballControls
import three.geometries.EdgesGeometry
import three.helpers.AxesHelper
import three.materials.Material
import three.math.*
import three.meshline.MeshLine
@ -50,14 +49,7 @@ public class ThreeCanvas(
private val raycaster = Raycaster()
private val mousePosition: Vector2 = Vector2()
private val scene: Scene = Scene().apply {
options.useProperty(Canvas3DOptions::axes, this) {
getObjectByName(AXES_NAME)?.let { remove(it) }
val axesObject = AxesHelper(axes.size.toInt()).apply { visible = axes.visible }
axesObject.name = AXES_NAME
add(axesObject)
}
}
private val scene: Scene = Scene()
private fun buildCamera(spec: CameraScheme) = PerspectiveCamera(

View File

@ -1,7 +1,7 @@
package space.kscience.visionforge.solid.three
import js.core.jso
import js.objects.jso
import space.kscience.dataforge.context.logger
import space.kscience.dataforge.context.warn
import space.kscience.visionforge.onPropertyChange
@ -27,7 +27,7 @@ public object ThreeLabelFactory : ThreeFactory<SolidLabel> {
return Mesh(textGeo, ThreeMaterials.DEFAULT).apply {
setMaterial(vision)
updatePosition(vision)
if(observe) {
if (observe) {
vision.onPropertyChange(three.context) {
//TODO
three.logger.warn { "Label parameter change not implemented" }

View File

@ -189,7 +189,7 @@ public class ThreePlugin : AbstractPlugin(), ComposeVisionRenderer {
@Composable
override fun DOMScope<Element>.render(client: VisionClient, name: Name, vision: Vision, meta: Meta) {
require(vision is Solid) { "Expected Solid but found ${vision::class}" }
ThreeView(solids, vision, null, Canvas3DOptions.read(meta))
ThreeView(context, vision, null, Canvas3DOptions.read(meta))
}
public companion object : PluginFactory<ThreePlugin> {

View File

@ -17,7 +17,6 @@ import space.kscience.visionforge.compose.*
import space.kscience.visionforge.root
import space.kscience.visionforge.solid.Solid
import space.kscience.visionforge.solid.SolidGroup
import space.kscience.visionforge.solid.Solids
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
import space.kscience.visionforge.solid.three.ThreeCanvas
import space.kscience.visionforge.solid.three.ThreePlugin
@ -63,7 +62,7 @@ private fun SimpleThreeView(
@Composable
public fun ThreeView(
solids: Solids,
context: Context,
solid: Solid?,
initialSelected: Name? = null,
options: Canvas3DOptions? = null,
@ -114,7 +113,7 @@ public fun ThreeView(
}
}
} else {
SimpleThreeView(solids.context, optionsSnapshot, solid, selected)
SimpleThreeView(context, optionsSnapshot, solid, selected)
}
key(selected) {
@ -136,7 +135,7 @@ public fun ThreeView(
NameCrumbs(selected) { selected = it }
Hr()
PropertyEditor(
scope = solids.context,
scope = context,
rootMeta = vision.properties.root(),
getPropertyState = { name ->
if (vision.properties.own?.get(name) != null) {
@ -189,6 +188,6 @@ public fun ThreeView(
}
}
} else {
SimpleThreeView(solids.context, optionsSnapshot, solid, selected)
SimpleThreeView(context, optionsSnapshot, solid, selected)
}
}