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

Make line width equal to point's stroke width #798

Merged
merged 9 commits into from
Jun 28, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object AesScaling {

fun lineWidth(p: DataPointAesthetics): Double {
// aes Units -> px
return p.linewidth()!! * 2.0
return p.linewidth()!! * UNIT_SHAPE_SIZE / 2.0
}

fun circleDiameter(p: DataPointAesthetics): Double {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ open class AestheticsDefaults(geomTheme: GeomTheme) {
put(Aes.ALPHA, geomTheme.alpha())
put(Aes.SIZE, geomTheme.size())
put(Aes.LINEWIDTH, geomTheme.lineWidth())
put(Aes.STROKE, geomTheme.lineWidth())
}
private val myDefaultsInLegend = TypedKeyHashMap()

Expand Down Expand Up @@ -96,7 +97,6 @@ open class AestheticsDefaults(geomTheme: GeomTheme) {
private fun lollipop(geomTheme: GeomTheme): AestheticsDefaults {
return point(geomTheme)
.update(Aes.SHAPE, NamedShape.STICK_CIRCLE)
.update(Aes.STROKE, 1.0)
}

private fun base(geomTheme: GeomTheme): AestheticsDefaults {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,35 +50,11 @@ object AestheticsUtil {
// else, override with color's alpha
}

fun strokeWidth(p: DataPointAesthetics): Double {
// aes Units -> px
return p.size()!! * 2.0
}
fun strokeWidth(p: DataPointAesthetics) = AesScaling.strokeWidth(p)

fun pointStrokeWidth(p: DataPointAesthetics): Double {
// aes Units -> px
return p.stroke()!! * AesScaling.UNIT_SHAPE_SIZE / 2.0
}
//
// fun circleDiameter(p: DataPointAesthetics): Double {
// // aes Units -> px
// return p.size()!! * 2.2
// }
//
// fun circleDiameterSmaller(p: DataPointAesthetics): Double {
// // aes Units -> px
// return p.size()!! * 1.5
// }
//
// fun sizeFromCircleDiameter(diameter: Double): Double {
// // px -> aes Units
// return diameter / 2.2
// }
//
fun textSize(p: DataPointAesthetics): Double {
// aes Units -> px
return p.size()!! * 2
}
fun pointStrokeWidth(p: DataPointAesthetics) = AesScaling.pointStrokeWidth(p)
alshan marked this conversation as resolved.
Show resolved Hide resolved

fun textSize(p: DataPointAesthetics) = AesScaling.textSize(p)

fun updateStroke(shape: SvgShape, p: DataPointAesthetics, applyAlpha: Boolean) {
shape.strokeColor().set(p.color())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,16 @@ class SmoothGeom : GeomBase() {
val dataPoints = ordered_X(with_X_Y(aesthetics.dataPoints()))
val helper = LinesHelper(pos, coord, ctx)

// Regression line
helper.setAlphaEnabled(false)
val regressionLines = helper.createLines(dataPoints, GeomUtil.TO_LOCATION_X_Y)
appendNodes(regressionLines, root)

// Confidence interval
helper.setAlphaFilter(PROPORTION)
helper.setWidthFilter(ZERO)
val bands = helper.createBands(dataPoints, GeomUtil.TO_LOCATION_X_YMAX, GeomUtil.TO_LOCATION_X_YMIN)
appendNodes(bands, root)

// Regression line
val regressionLines = helper.createLines(dataPoints, GeomUtil.TO_LOCATION_X_Y)
appendNodes(regressionLines, root)

buildHints(dataPoints, pos, coord, ctx)
}

Expand All @@ -66,7 +65,7 @@ class SmoothGeom : GeomBase() {
)
.defaultColor(
p.fill()!!,
PROPORTION(p.alpha())
p.alpha()
)

val hintsCollection = HintsCollection(p, helper)
Expand All @@ -87,8 +86,5 @@ class SmoothGeom : GeomBase() {

companion object {
const val HANDLES_GROUPS = true

private val PROPORTION = { v: Double? -> if (v == null) null else v / 10 }
private val ZERO = { _: Double? -> 0.0 }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import jetbrains.datalore.plot.common.geometry.PolylineSimplifier
open class LinesHelper(pos: PositionAdjustment, coord: CoordinateSystem, ctx: GeomContext) :
GeomHelper(pos, coord, ctx) {

private var myAlphaFilter = { v: Double? -> v }
private var myWidthFilter = { v: Double? -> v }
private var myAlphaEnabled = true

private fun insertPathSeparators(rings: Iterable<List<DoubleVector>>): List<DoubleVector?> {
Expand Down Expand Up @@ -139,7 +137,8 @@ open class LinesHelper(pos: PositionAdjustment, coord: CoordinateSystem, ctx: Ge

if (!points.isEmpty()) {
val path = LinePath.polygon(points)
//decorate(path, groupDataPoints.get(0), true);
// to retain the side edges of area:
// decorate(path, groupDataPoints.get(0), true);
decorateFillingPart(path, groupDataPoints[0])
lines.add(path)
}
Expand All @@ -159,7 +158,7 @@ open class LinesHelper(pos: PositionAdjustment, coord: CoordinateSystem, ctx: Ge
strokeScaler: (DataPointAesthetics) -> Double = AesScaling::strokeWidth
) {
val stroke = p.color()
val strokeAlpha = myAlphaFilter(AestheticsUtil.alpha(stroke!!, p))!!
val strokeAlpha = AestheticsUtil.alpha(stroke!!, p)
path.color().set(withOpacity(stroke, strokeAlpha))
if (!AestheticsUtil.ALPHA_CONTROLS_BOTH && (filled || !myAlphaEnabled)) {
path.color().set(stroke)
Expand All @@ -169,7 +168,7 @@ open class LinesHelper(pos: PositionAdjustment, coord: CoordinateSystem, ctx: Ge
decorateFillingPart(path, p)
}

val size = myWidthFilter(strokeScaler(p))!!
val size = strokeScaler(p)
path.width().set(size)

val lineType = p.lineType()
Expand All @@ -180,18 +179,10 @@ open class LinesHelper(pos: PositionAdjustment, coord: CoordinateSystem, ctx: Ge

private fun decorateFillingPart(path: LinePath, p: DataPointAesthetics) {
val fill = p.fill()
val fillAlpha = myAlphaFilter(AestheticsUtil.alpha(fill!!, p))!!
val fillAlpha = AestheticsUtil.alpha(fill!!, p)
path.fill().set(withOpacity(fill, fillAlpha))
}

fun setAlphaFilter(alphaFilter: (Double?) -> Double?) {
myAlphaFilter = alphaFilter
}

fun setWidthFilter(widthFilter: (Double?) -> Double?) {
myWidthFilter = widthFilter
}

// ToDo: get rid of PathInfo class
class PathInfo internal constructor(val path: LinePath)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import jetbrains.datalore.plot.builder.assemble.geom.PointDataAccess
import jetbrains.datalore.plot.builder.data.DataProcessing
import jetbrains.datalore.plot.builder.data.GroupingContext
import jetbrains.datalore.plot.builder.data.StatInput
import jetbrains.datalore.plot.builder.defaultTheme.DefaultGeomTheme
import jetbrains.datalore.plot.builder.interact.ContextualMappingProvider
import jetbrains.datalore.plot.builder.presentation.DefaultFontFamilyRegistry
import jetbrains.datalore.plot.builder.presentation.FontFamilyRegistry
Expand Down Expand Up @@ -72,7 +71,7 @@ class GeomLayerBuilder(

private var myAnnotationsProvider: ((MappedDataAccess, DataFrame) -> Annotations?)? = null

private var myGeomTheme: GeomTheme = DefaultGeomTheme.BASE
private lateinit var myGeomTheme: GeomTheme

fun addBinding(v: VarBinding): GeomLayerBuilder {
myBindings.add(v)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ internal class DefaultGeomTheme private constructor(
override fun lineWidth() = lineWidth

companion object {
val BASE = DefaultGeomTheme(
color = Color.PACIFIC_BLUE,
fill = Color.PACIFIC_BLUE,
alpha = 1.0,
size = 0.5,
lineWidth = 0.5
)

internal class InheritedColors(
options: Map<String, Any>,
fontFamilyRegistry: FontFamilyRegistry
Expand All @@ -61,13 +53,24 @@ internal class DefaultGeomTheme private constructor(
}
}

private class FixedColors(geomKind: GeomKind) {
val color = if (geomKind == GeomKind.SMOOTH) {
Color.MAGENTA
} else {
Color.PACIFIC_BLUE
}
val fill = Color.PACIFIC_BLUE
}

// defaults for geomKind
fun forGeomKind(geomKind: GeomKind, inheritedColors: InheritedColors): GeomTheme {
var color = BASE.color
var fill = BASE.fill
var alpha = BASE.alpha
var size = BASE.size
val lineWidth = BASE.lineWidth
val fixedColors = FixedColors(geomKind)

var color = fixedColors.color
var fill = fixedColors.fill
var alpha = 1.0
var size = 0.6
var lineWidth = 0.6

when (geomKind) {
GeomKind.PATH,
Expand All @@ -88,8 +91,6 @@ internal class DefaultGeomTheme private constructor(
}

GeomKind.HISTOGRAM,
GeomKind.CROSS_BAR,
GeomKind.BOX_PLOT,
GeomKind.AREA_RIDGES,
GeomKind.VIOLIN,
GeomKind.AREA,
Expand All @@ -105,28 +106,40 @@ internal class DefaultGeomTheme private constructor(
color = inheritedColors.lineColor()
fill = inheritedColors.lineColor()
alpha = 0.1
size = 0.2
size = 0.24
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract the experimental multiplier (1.2) to a val .

}

GeomKind.POINT_RANGE -> {
GeomKind.CROSS_BAR,
GeomKind.BOX_PLOT -> {
color = inheritedColors.lineColor()
fill = Colors.withOpacity(inheritedColors.lineColor(), 0.1)
fill = inheritedColors.backgroundFill()
}

GeomKind.POINT,
GeomKind.JITTER,
GeomKind.Q_Q,
GeomKind.Q_Q_2,
GeomKind.Q_Q_2 -> {
color = inheritedColors.lineColor()
fill = inheritedColors.backgroundFill()
size = 2.4
}

GeomKind.POINT_RANGE -> {
color = inheritedColors.lineColor()
fill = inheritedColors.backgroundFill()
lineWidth = 1.2 // line width and stroke for point
}

GeomKind.LOLLIPOP -> {
color = inheritedColors.lineColor()
fill = Colors.withOpacity(inheritedColors.lineColor(), 0.1)
fill = inheritedColors.backgroundFill()
size = 2.0
lineWidth = 1.2 // line width and stroke for point
}

GeomKind.SMOOTH -> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is bad: alpha = 1.5


                GeomKind.SMOOTH -> {
                    color = Color.MAGENTA

We don't want to use constant values no longer. Should be a field in BASE (but still get rid of the BASE).

color = Color.MAGENTA
fill = inheritedColors.lineColor()
alpha = 1.5 // Geometry uses (value / 10) for alpha: SmoothGeom.kt:91 (PROPORTION)
alpha = 0.15
}

GeomKind.DOT_PLOT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

package jetbrains.datalore.plot.builder.assemble

import jetbrains.datalore.base.values.Color
import jetbrains.datalore.plot.base.*
import jetbrains.datalore.plot.base.aes.GeomTheme
import jetbrains.datalore.plot.base.scale.Scales
import jetbrains.datalore.plot.base.stat.Stats
import jetbrains.datalore.plot.builder.VarBinding
Expand Down Expand Up @@ -73,6 +75,13 @@ class GeomLayerBuilderTest {
// .geom(geomProvider)
// .pos(posProvider)
// .addConstantAes(Aes.ALPHA, 0.5)
.geomTheme(object : GeomTheme {
override fun color(): Color = Color.PACIFIC_BLUE
override fun fill(): Color = Color.PACIFIC_BLUE
override fun alpha() = 1.0
override fun size() = 0.5
override fun lineWidth() = 0.5
})
.addBinding(bindings[0])
.addBinding(bindings[1])
.build(data, scaleByAes, scaleMappersNP)
Expand All @@ -94,4 +103,5 @@ class GeomLayerBuilderTest {
// checkNotOriginalVar(layerData, histogramLayer.getBinding(Aes.Y))
checkNotOriginalVar(layerData, histogramLayer.getBinding(Aes.FILL))
}

}