Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interactivity: wheel tool fix for firefox #1116

Merged
merged 5 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Next Next commit
WIP
  • Loading branch information
IKupriyanov-HORIS committed Jun 7, 2024
commit 30c831d9b95ca1b88be9fa5e0e09e703f2bd777c
739 changes: 700 additions & 39 deletions docs/dev/notebooks/interactive_tools.ipynb

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions js-package/src/jsMain/kotlin/FigureModelJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/

import org.jetbrains.letsPlot.commons.event.MouseEventSource
import org.jetbrains.letsPlot.commons.logging.PortableLogging
import org.jetbrains.letsPlot.commons.registration.Registration
import org.jetbrains.letsPlot.core.interact.event.ToolEventDispatcher
Expand Down Expand Up @@ -49,6 +50,7 @@ class FigureModelJs internal constructor(
monolithicParameters.width,
monolithicParameters.height,
monolithicParameters.parentElement,
monolithicParameters.mouseEventSource,
monolithicParameters.options
)

Expand Down Expand Up @@ -89,5 +91,6 @@ internal class MonolithicParameters(
val width: Double,
val height: Double,
val parentElement: HTMLElement,
val mouseEventSource: MouseEventSource,
val options: Map<String, Any>
)
28 changes: 20 additions & 8 deletions js-package/src/jsMain/kotlin/FigureToHtml.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import kotlinx.browser.document
import kotlinx.browser.window
import kotlinx.dom.createElement
import org.jetbrains.letsPlot.commons.event.MouseEventSource
import org.jetbrains.letsPlot.commons.geometry.DoubleRectangle
import org.jetbrains.letsPlot.commons.geometry.DoubleVector
import org.jetbrains.letsPlot.commons.geometry.Vector
Expand Down Expand Up @@ -35,7 +36,8 @@ import org.w3c.dom.svg.SVGSVGElement

internal class FigureToHtml(
private val buildInfo: FigureBuildInfo,
private val containerElement: HTMLElement
private val containerElement: HTMLElement,
private val mouseEventSource: MouseEventSource
) {

private val parentElement: HTMLElement = if (buildInfo.isComposite) {
Expand All @@ -52,6 +54,10 @@ internal class FigureToHtml(
fun eval(): Result {

val buildInfo = buildInfo.layoutedByOuterSize()
containerElement.style.apply {
width = "${buildInfo.layoutInfo.figureSize.x}px"
height = "${buildInfo.layoutInfo.figureSize.y}px"
}

buildInfo.injectLiveMapProvider { tiles: List<List<GeomLayer>>, spec: Map<String, Any> ->
val cursorServiceConfig = CursorServiceConfig()
Expand All @@ -64,12 +70,14 @@ internal class FigureToHtml(
processCompositeFigure(
svgRoot,
origin = null, // The topmost SVG
parentElement = parentElement
parentElement = parentElement,
mouseEventSource = mouseEventSource
)
} else {
processPlotFigure(
svgRoot as PlotSvgRoot,
parentElement = parentElement
parentElement = parentElement,
eventMapper = mouseEventSource
)
}

Expand All @@ -96,10 +104,11 @@ internal class FigureToHtml(
private fun processPlotFigure(
svgRoot: PlotSvgRoot,
parentElement: HTMLElement,
eventMapper: MouseEventSource
): ToolEventDispatcher {

val plotContainer = PlotContainer(svgRoot)
val rootSVG: SVGSVGElement = buildPlotFigureSVG(plotContainer, parentElement)
val rootSVG: SVGSVGElement = buildPlotFigureSVG(plotContainer, parentElement, eventMapper)
rootSVG.style.setCursor(CssCursor.CROSSHAIR)

// Livemap cursor pointer
Expand All @@ -117,6 +126,7 @@ internal class FigureToHtml(
svgRoot: CompositeFigureSvgRoot,
origin: DoubleVector?,
parentElement: HTMLElement,
mouseEventSource: MouseEventSource
): ToolEventDispatcher {
svgRoot.ensureContentBuilt()

Expand Down Expand Up @@ -151,11 +161,12 @@ internal class FigureToHtml(
}
processPlotFigure(
svgRoot = figureSvgRoot,
parentElement = figureContainer
parentElement = figureContainer,
eventMapper = mouseEventSource
)
} else {
figureSvgRoot as CompositeFigureSvgRoot
processCompositeFigure(figureSvgRoot, elementOrigin, parentElement)
processCompositeFigure(figureSvgRoot, elementOrigin, parentElement, mouseEventSource)
}
}

Expand Down Expand Up @@ -187,7 +198,8 @@ internal class FigureToHtml(

private fun buildPlotFigureSVG(
plotContainer: PlotContainer,
parentElement: Element
parentElement: Element,
mouseEventSource: MouseEventSource
): SVGSVGElement {

val svg: SVGSVGElement = mapSvgToSVG(plotContainer.svg)
Expand All @@ -198,7 +210,7 @@ internal class FigureToHtml(
}
}

plotContainer.mouseEventPeer.addEventSource(DomMouseEventMapper(svg))
plotContainer.mouseEventPeer.addEventSource(mouseEventSource)

plotContainer.liveMapFigures.forEach { liveMapFigure ->
val bounds = (liveMapFigure as CanvasFigure).bounds().get()
Expand Down
34 changes: 27 additions & 7 deletions js-package/src/jsMain/kotlin/MonolithicJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@

/* root package */

import kotlinx.browser.document
import org.jetbrains.letsPlot.commons.event.MouseEventSource
import org.jetbrains.letsPlot.commons.geometry.DoubleRectangle
import org.jetbrains.letsPlot.commons.geometry.DoubleVector
import org.jetbrains.letsPlot.commons.logging.PortableLogging
import org.jetbrains.letsPlot.core.platf.dom.DomMouseEventMapper
import org.jetbrains.letsPlot.core.plot.builder.FigureBuildInfo
import org.jetbrains.letsPlot.core.spec.FailureHandler
import org.jetbrains.letsPlot.core.spec.config.PlotConfig
import org.jetbrains.letsPlot.core.util.MonolithicCommon
import org.jetbrains.letsPlot.core.util.MonolithicCommon.PlotsBuildResult.Error
import org.jetbrains.letsPlot.core.util.MonolithicCommon.PlotsBuildResult.Success
import org.jetbrains.letsPlot.platf.w3c.jsObject.dynamicObjectToMap
import org.w3c.dom.HTMLDivElement
import org.w3c.dom.HTMLElement
import org.w3c.dom.HTMLParagraphElement
import org.w3c.dom.get
Expand Down Expand Up @@ -50,7 +54,12 @@ fun buildPlotFromRawSpecs(
} else {
emptyMap()
}
buildPlotFromProcessedSpecsIntern(processedSpec, width, height, parentElement, options)

val figureContainer = document.createElement("div") as HTMLDivElement
val mouseEventSource = DomMouseEventMapper(figureContainer)

parentElement.appendChild(figureContainer)
buildPlotFromProcessedSpecsIntern(processedSpec, width, height, figureContainer, mouseEventSource, options)
} catch (e: RuntimeException) {
handleException(e, parentElement)
null
Expand Down Expand Up @@ -83,7 +92,12 @@ fun buildPlotFromProcessedSpecs(
} else {
emptyMap()
}
buildPlotFromProcessedSpecsIntern(processedSpec, width, height, parentElement, options)

val figureContainer = document.createElement("div") as HTMLDivElement
parentElement.appendChild(figureContainer)
val mouseEventSource = DomMouseEventMapper(figureContainer)

buildPlotFromProcessedSpecsIntern(processedSpec, width, height, figureContainer, mouseEventSource, options)
} catch (e: RuntimeException) {
handleException(e, parentElement)
null
Expand All @@ -95,6 +109,7 @@ internal fun buildPlotFromProcessedSpecsIntern(
width: Double,
height: Double,
parentElement: HTMLElement,
mouseEventSource: MouseEventSource,
options: Map<String, Any>
): FigureModelJs? {

Expand Down Expand Up @@ -145,23 +160,27 @@ internal fun buildPlotFromProcessedSpecsIntern(
val figureModel = if (success.buildInfos.size == 1) {
// a single figure
val buildInfo = success.buildInfos[0]
val result = FigureToHtml(buildInfo, parentElement).eval()
val result = FigureToHtml(buildInfo, parentElement, mouseEventSource).eval()
FigureModelJs(
plotSpec,
MonolithicParameters(width, height, parentElement, options),
MonolithicParameters(width, height, parentElement, mouseEventSource, options),
result.toolEventDispatcher,
result.figureRegistration
)
} else {
// a bunch
buildGGBunchComponent(success.buildInfos, parentElement)
buildGGBunchComponent(success.buildInfos, parentElement, mouseEventSource)
null
}

return figureModel
}

fun buildGGBunchComponent(plotInfos: List<FigureBuildInfo>, parentElement: HTMLElement) {
fun buildGGBunchComponent(
plotInfos: List<FigureBuildInfo>,
parentElement: HTMLElement,
mouseEventSource: MouseEventSource
) {
val bunchBounds = plotInfos.map { it.bounds }
.fold(DoubleRectangle(DoubleVector.ZERO, DoubleVector.ZERO)) { acc, bounds ->
acc.union(bounds)
Expand All @@ -179,7 +198,8 @@ fun buildGGBunchComponent(plotInfos: List<FigureBuildInfo>, parentElement: HTMLE

FigureToHtml(
buildInfo = plotInfo,
containerElement = itemContainerElement
containerElement = itemContainerElement,
mouseEventSource = mouseEventSource
).eval()

}
Expand Down