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

Improve border line type experience #1106

Merged
merged 8 commits into from
May 24, 2024
3 changes: 2 additions & 1 deletion future_changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
- Undesired vertical scroller when displaying `gggrid` in Jupyter notebook.
- GeoJson structure breaks if the ring start label occurs several times [[#1086](https://github.com/JetBrains/lets-plot/issues/1086)].
- `theme`: left margin doesn't work for the `plot_title` parameter [[#1101](https://github.com/JetBrains/lets-plot/issues/1101)].
- Support for marker rotation [[#736](https://github.com/JetBrains/lets-plot/issues/736)].
- Support for marker rotation [[#736](https://github.com/JetBrains/lets-plot/issues/736)].
- Improve border line type experience [[LPK-220](https://github.com/JetBrains/lets-plot-kotlin/issues/220)].
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,17 @@ class BoxplotGeom : GeomBase() {
ctx: GeomContext,
geomHelper: GeomHelper
) {
BoxHelper.buildMidlines(root, aesthetics, middleAesthetic = Aes.MIDDLE, ctx, geomHelper, fatten = fattenMidline)
BoxHelper.buildMidlines(
root,
aesthetics,
xAes = Aes.X,
middleAes = Aes.MIDDLE,
sizeAes = Aes.WIDTH,
ctx,
geomHelper,
fatten = fattenMidline,
flip = false
)

val elementHelper = geomHelper.createSvgElementHelper()
for (p in aesthetics.dataPoints()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import org.jetbrains.letsPlot.core.plot.base.geom.util.GeomHelper
import org.jetbrains.letsPlot.core.plot.base.geom.util.HintColorUtil
import org.jetbrains.letsPlot.core.plot.base.render.LegendKeyElementFactory
import org.jetbrains.letsPlot.core.plot.base.render.SvgRoot
import org.jetbrains.letsPlot.datamodel.svg.dom.SvgShape

class CrossBarGeom(
private val isVertical: Boolean
Expand Down Expand Up @@ -48,10 +47,6 @@ class CrossBarGeom(
return flipHelper.flip(rectangle)
}

private fun afterRotation(vector: DoubleVector): DoubleVector {
return flipHelper.flip(vector)
}

override fun buildIntern(
root: SvgRoot,
aesthetics: Aesthetics,
Expand All @@ -64,7 +59,17 @@ class CrossBarGeom(
root, aesthetics, pos, coord, ctx,
rectFactory = clientRectByDataPoint(ctx, geomHelper, isHintRect = false)
)
buildMidlines(root, aesthetics, ctx, geomHelper, fatten = fattenMidline)
BoxHelper.buildMidlines(
root,
aesthetics,
xAes = afterRotation(Aes.X),
middleAes = afterRotation(Aes.Y),
sizeAes = Aes.WIDTH, // do not flip as height is not defined for CrossBarGeom
ctx,
geomHelper,
fatten = fattenMidline,
flip = !isVertical
)
// tooltip
flipHelper.buildHints(
listOf(Aes.YMIN, Aes.YMAX).map(::afterRotation),
Expand Down Expand Up @@ -114,39 +119,6 @@ class CrossBarGeom(
}
}

private fun buildMidlines(
root: SvgRoot,
aesthetics: Aesthetics,
ctx: GeomContext,
geomHelper: GeomHelper,
fatten: Double
) {
val elementHelper = geomHelper.createSvgElementHelper()
val xAes = afterRotation(Aes.X)
val yAes = afterRotation(Aes.Y)
val sizeAes = Aes.WIDTH // do not flip as height is not defined for CrossBarGeom
for (p in aesthetics.dataPoints()) {
val x = p.finiteOrNull(xAes) ?: continue
val middle = p.finiteOrNull(yAes) ?: continue
val w = p.finiteOrNull(sizeAes) ?: continue

val width = w * ctx.getResolution(xAes)
val (line) = elementHelper.createLine(
afterRotation(DoubleVector(x - width / 2, middle)),
afterRotation(DoubleVector(x + width / 2, middle)),
p
) ?: continue

// TODO: use strokeScale in createLine() function
// adjust thickness
require(line is SvgShape)
val thickness = line.strokeWidth().get()!!
line.strokeWidth().set(thickness * fatten)

root.add(line)
}
}

companion object {
const val HANDLES_GROUPS = false
private val LEGEND_FACTORY = BoxHelper.legendFactory(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,30 @@ object BoxHelper {
fun buildMidlines(
root: SvgRoot,
aesthetics: Aesthetics,
middleAesthetic: Aes<Double>,
xAes: Aes<Double>,
middleAes: Aes<Double>,
sizeAes: Aes<Double>,
ctx: GeomContext,
geomHelper: GeomHelper,
fatten: Double
fatten: Double,
flip: Boolean
) {
val elementHelper = geomHelper.createSvgElementHelper()
for (p in aesthetics.dataPoints()) {
val x = p.finiteOrNull(Aes.X) ?: continue
val middle = p.finiteOrNull(middleAesthetic) ?: continue
val w = p.finiteOrNull(Aes.WIDTH) ?: continue
val x = p.finiteOrNull(xAes) ?: continue
val middle = p.finiteOrNull(middleAes) ?: continue
val w = p.finiteOrNull(sizeAes) ?: continue

val width = w * ctx.getResolution(Aes.X)
val width = w * ctx.getResolution(xAes)

val (line) = elementHelper.createLine(
DoubleVector(x - width / 2, middle),
DoubleVector(x + width / 2, middle),
DoubleVector(x - width / 2, middle).flipIf(flip),
DoubleVector(x + width / 2, middle).flipIf(flip),
p
) ?: continue
) { AesScaling.strokeWidth(it) * fatten } ?: continue

// TODO: use strokeScale in createLine() function
// adjust thickness
require(line is SvgShape)
val thickness = line.strokeWidth().get()!!
line.strokeWidth().set(thickness * fatten)

root.add(line)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ enum class NamedLineType(val code: Int, private val myDashArray: List<Double>?)
override val isSolid: Boolean
get() = true
},
DASHED(2, listOf(4.3, 4.3)),
DOTTED(3, listOf(1.0, 3.2)),
DASHED(2, listOf(4.0, 4.0)),
DOTTED(3, listOf(1.0, 3.0)),
@Suppress("SpellCheckingInspection")
DOTDASH(4, listOf(1.0, 3.2, 4.3, 3.2)),
DOTDASH(4, listOf(1.0, 3.0, 4.0, 3.0)),
@Suppress("SpellCheckingInspection")
LONGDASH(5, listOf(7.4, 3.2)),
LONGDASH(5, listOf(7.0, 3.0)),
@Suppress("SpellCheckingInspection")
TWODASH(6, listOf(2.4, 2.4, 6.4, 2.4));
TWODASH(6, listOf(2.0, 2.0, 6.0, 2.0));

override val isSolid: Boolean
get() = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class PathConverterTest {

matcher!!
.strokeWidth(eq(1.1))
.lineDash(vectorEq(listOf(4.73, 4.73)))
.lineDash(vectorEq(listOf(4.4, 4.4)))

assertMapObject()
}
Expand All @@ -61,7 +61,7 @@ class PathConverterTest {

matcher!!
.strokeWidth(eq(4.4))
.lineDash(vectorEq(listOf(18.92, 18.92)))
.lineDash(vectorEq(listOf(17.6, 17.6)))

assertMapObject()
}
Expand Down