This is an automated email from the ASF dual-hosted git repository. joergrade pushed a commit to branch spring6-kroviz in repository https://gitbox.apache.org/repos/asf/causeway.git
commit a30c7671b628da47e418df90786f1fb3c6996fc4 Author: Jörg Rade <[email protected]> AuthorDate: Thu Apr 27 20:10:52 2023 +0200 CAUSEWAY-3264 show vega in sample --- examples/demo/.run/DemoAppWicketJpa.run.xml | 2 + .../apache/causeway/client/kroviz/to/TypeMapper.kt | 5 +- .../client/kroviz/ui/core/FormPanelFactory.kt | 19 +- .../causeway/client/kroviz/ui/core/RoMenuBar.kt | 10 +- .../causeway/client/kroviz/ui/dialog/VegaPanel.kt | 218 +++++++++++++++++++++ .../apache/causeway/client/kroviz/utils/js/Vega.kt | 29 +++ 6 files changed, 271 insertions(+), 12 deletions(-) diff --git a/examples/demo/.run/DemoAppWicketJpa.run.xml b/examples/demo/.run/DemoAppWicketJpa.run.xml index f768659871..32ef270280 100644 --- a/examples/demo/.run/DemoAppWicketJpa.run.xml +++ b/examples/demo/.run/DemoAppWicketJpa.run.xml @@ -1,6 +1,8 @@ <component name="ProjectRunConfigurationManager"> <configuration default="false" name="DemoAppWicketJpa" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot"> <option name="ACTIVE_PROFILES" value="port9090" /> + <option name="ALTERNATIVE_JRE_PATH" value="17" /> + <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" /> <module name="demo-wicket-jpa" /> <option name="SHORTEN_COMMAND_LINE" value="ARGS_FILE" /> <option name="SPRING_BOOT_MAIN_CLASS" value="demoapp.webapp.wicket.jpa.DemoAppWicketJpa" /> diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/to/TypeMapper.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/to/TypeMapper.kt index 21f93b7633..29523671ac 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/to/TypeMapper.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/to/TypeMapper.kt @@ -37,7 +37,7 @@ enum class ValueType(val type: String) { SHELL("Shell"), SVG_MAPPED("Map"), SVG_INLINE("Inline"), - VEGA("Vega"), + CANVAS("Canvas"), } class TypeMapper { @@ -68,6 +68,7 @@ class TypeMapper { XmlHelper.isXml(contentStr) -> ValueType.HTML.type contentStr.startsWith(":Notice:") -> ValueType.HTML.type contentStr.startsWith("link:") -> ValueType.HTML.type + contentStr.contains("vega.github.io/schema") -> ValueType.CANVAS.type else -> ValueType.TEXT.type } } @@ -89,7 +90,7 @@ class TypeMapper { ValueType.SLIDER.type -> return ValueType.SLIDER ValueType.SVG_MAPPED.type -> return ValueType.SVG_MAPPED ValueType.SVG_INLINE.type -> return ValueType.SVG_INLINE - ValueType.VEGA.type -> return ValueType.VEGA + ValueType.CANVAS.type -> return ValueType.CANVAS else -> { return ValueType.TEXT } diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/FormPanelFactory.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/FormPanelFactory.kt index d5ab217f30..8ac0c2ba6e 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/FormPanelFactory.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/FormPanelFactory.kt @@ -32,10 +32,7 @@ import io.kvision.form.text.Text import io.kvision.form.text.TextArea import io.kvision.form.time.DateTime import io.kvision.form.time.dateTime -import io.kvision.html.Button -import io.kvision.html.Div -import io.kvision.html.Iframe -import io.kvision.html.Image +import io.kvision.html.* import io.kvision.panel.VPanel import io.kvision.panel.vPanel import io.kvision.utils.auto @@ -74,8 +71,8 @@ class FormPanelFactory(items: List<FormItem>) : VPanel() { ValueType.SVG_INLINE -> add(createInline(fi)) ValueType.SVG_MAPPED -> add(createSvgMap(fi)) ValueType.BUTTON -> add(createButton(fi)) - ValueType.VEGA -> { - TODO("implement VEGA") + ValueType.CANVAS -> add(createCanvas(fi)) + else -> { } } } @@ -245,6 +242,16 @@ class FormPanelFactory(items: List<FormItem>) : VPanel() { return item } + private fun createCanvas(fi: FormItem): VPanel { + val item = VPanel { + val vega = fi.content as String + val canvas = Canvas() + + add(canvas) + } + return item + } + companion object { private const val FORM_PANEL = "form-panel" } diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/RoMenuBar.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/RoMenuBar.kt index 569d385c6c..bf915b3ddb 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/RoMenuBar.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/RoMenuBar.kt @@ -35,10 +35,7 @@ import org.apache.causeway.client.kroviz.core.Session import org.apache.causeway.client.kroviz.core.aggregator.ActionDispatcher import org.apache.causeway.client.kroviz.core.event.ResourceProxy import org.apache.causeway.client.kroviz.to.mb.Menubars -import org.apache.causeway.client.kroviz.ui.dialog.About -import org.apache.causeway.client.kroviz.ui.dialog.EventDialog -import org.apache.causeway.client.kroviz.ui.dialog.LoginPrompt -import org.apache.causeway.client.kroviz.ui.dialog.SvgInline +import org.apache.causeway.client.kroviz.ui.dialog.* import org.apache.causeway.client.kroviz.ui.menu.DropDownMenuBuilder import org.apache.causeway.client.kroviz.ui.panel.GeoMap import org.apache.causeway.client.kroviz.ui.panel.ImageSample @@ -204,6 +201,11 @@ class RoMenuBar : SimplePanel() { buildMenuEntry(imageTitle, "Image", { ViewManager.add(imageTitle, ImageSample) }) ) + val vegaTitle = "Vega Sample" + subMenu.add( + buildMenuEntry(vegaTitle, "Image", { ViewManager.add(vegaTitle, VegaPanel()) }) + ) + mainMenu.add(subMenu) return mainMenu diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/dialog/VegaPanel.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/dialog/VegaPanel.kt new file mode 100644 index 0000000000..b86af96572 --- /dev/null +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/dialog/VegaPanel.kt @@ -0,0 +1,218 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.causeway.client.kroviz.ui.dialog + +import io.kvision.utils.obj +import org.apache.causeway.client.kroviz.core.event.ReplayController +import org.apache.causeway.client.kroviz.to.ValueType +import org.apache.causeway.client.kroviz.ui.core.FormItem +import org.apache.causeway.client.kroviz.ui.core.RoDialog +import org.apache.causeway.client.kroviz.ui.core.ViewManager +import io.kvision.panel.SimplePanel +import org.apache.causeway.client.kroviz.utils.js.Vega + +class VegaPanel : SimplePanel() { + + //Default values + val spec = obj { + this["\$schema"] = "https://vega.github.io/schema/vega/v5.json" + this.description = "A basic bar chart example, with value labels shown upon mouse hover." + this.width = 400 + this.height = 200 + this.padding = 5 + this.data = arrayOf( + obj { + this.name = "table" + this.values = arrayOf( + obj { + this.category = "A" + this.amount = 28 + }, + obj { + this.category = "B" + this.amount = 55 + }, + obj { + this.category = "C" + this.amount = 43 + }, + obj { + this.category = "D" + this.amount = 91 + }, + obj { + this.category = "E" + this.amount = 81 + }, + obj { + this.category = "F" + this.amount = 53 + }, + obj { + this.category = "G" + this.amount = 19 + }, + obj { + this.category = "H" + this.amount = 87 + } + ) + } + ) + this.signals = arrayOf( + obj { + this.name = "tooltip" + this.value = obj { + } + this.on = arrayOf( + obj { + this.events = "rect:mouseover" + this.update = "datum" + }, + obj { + this.events = "rect:mouseout" + this.update = "{}" + } + ) + } + ) + this.scales = arrayOf( + obj { + this.name = "xscale" + this.type = "band" + this.domain = obj { + this.data = "table" + this.field = "category" + } + this.range = "width" + this.padding = 0.05 + this.round = true + }, + obj { + this.name = "yscale" + this.domain = obj { + this.data = "table" + this.field = "amount" + } + this.nice = true + this.range = "height" + } + ) + this.axes = arrayOf( + obj { + this.orient = "bottom" + this.scale = "xscale" + }, + obj { + this.orient = "left" + this.scale = "yscale" + } + ) + this.marks = arrayOf( + obj { + this.type = "rect" + this.from = obj { + this.data = "table" + } + this.encode = obj { + this.enter = obj { + this.x = obj { + this.scale = "xscale" + this.field = "category" + } + this.width = obj { + this.scale = "xscale" + this.band = 1 + } + this.y = obj { + this.scale = "yscale" + this.field = "amount" + } + this.y2 = obj { + this.scale = "yscale" + this.value = 0 + } + } + this.update = obj { + this.fill = obj { + this.value = "steelblue" + } + } + this.hover = obj { + this.fill = obj { + this.value = "red" + } + } + } + }, + obj { + this.type = "text" + this.encode = obj { + this.enter = obj { + this.align = obj { + this.value = "center" + } + this.baseline = obj { + this.value = "bottom" + } + this.fill = obj { + this.value = "#333" + } + } + this.update = obj { + this.x = obj { + this.scale = "xscale" + this.signal = "tooltip.category" + this.band = 0.5 + } + this.y = obj { + this.scale = "yscale" + this.signal = "tooltip.amount" + this.offset = -2 + } + this.text = obj { + this.signal = "tooltip.amount" + } + this.fillOpacity = arrayOf( + obj { + this.test = "datum === tooltip" + this.value = 0 + }, + obj { + this.value = 1 + } + ) + } + } + } + ) + } + + init { + this.addAfterInsertHook { + val view = Vega.View(Vega.parse(spec), obj { + this.renderer = "canvas" + this.container = getElement() + this.hover = true + }) + view.runAsync() + } + } + +} diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/Vega.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/Vega.kt new file mode 100644 index 0000000000..0e899436b2 --- /dev/null +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/Vega.kt @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.causeway.client.kroviz.utils.js + +@JsModule("vega") +@JsNonModule +external object Vega { + fun parse(spec: dynamic): dynamic + class View(spec: dynamic, options: dynamic) { + fun runAsync() + } + +}
