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

Add element_geom(pen, brush, paper) #836

Merged
merged 15 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class EmptyGeomContext : GeomContext {
override val flipped: Boolean = false
override val targetCollector: GeomTargetCollector = NullGeomTargetCollector()
override val annotations: Annotations? = null
override val plotBackground: Color = Color.WHITE
override val backgroundColor: Color = Color.WHITE

override fun getResolution(aes: org.jetbrains.letsPlot.core.plot.base.Aes<Double>): Double {
throw IllegalStateException("Not available in an empty geom context")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,90 @@ import demoAndTestShared.parsePlotSpec
class NamedSystemColors {
fun plotSpecList(): List<MutableMap<String, Any>> {
return listOf(
withFlavor(null),
withFlavor("solarized_light"),
withFlavor("solarized_dark"),
withFlavor("solarized_dark", background = "dark_blue"),
pieChart(),
pieChart(flavor = "darcula"),
pieChart(flavor = "solarized_light"),
pieChart(flavor = "solarized_dark"),
pieChart(flavor = "high_contrast_light"),
pieChart(flavor = "high_contrast_dark"),
pieChart(flavor = "darcula", withCustomColors = true, flavorOverCustomColors = true),
pieChart(flavor = "darcula", withCustomColors = true, flavorOverCustomColors = false)
)
}

private fun withFlavor(flavor: String?, background: String? = null): MutableMap<String, Any> {
private fun pieChart(
theme: String = "grey",
flavor: String? = null,
withCustomColors: Boolean = false,
flavorOverCustomColors: Boolean = true
): MutableMap<String, Any> {
val flavorOpts = flavor?.let { "'flavor': '$flavor'" } ?: ""
val customColors = if (withCustomColors) {
"'geom': { 'pen': 'red', 'paper': 'green', 'brush': 'blue' }"
} else {
""
}

val themeSettings = (
listOf(
"'name': '$theme'"
) + if (flavorOverCustomColors) {
listOf(customColors, flavorOpts)
} else {
listOf(flavorOpts, customColors)
})
.filter(String::isNotEmpty)
.joinToString()

val spec = """
{
'data': {
'name': ['pen', 'brush', 'paper']
},
'theme': { $themeSettings },
'ggtitle': { 'text': 'theme=$theme, flavor=$flavor, custom colors=$withCustomColors,
${if (flavorOverCustomColors) "theme() + flavor()" else "flavor() + theme()"}' },
'kind': 'plot',
'scales': [
{
'aesthetic': 'fill',
'values': ['pen', 'brush', 'paper']
}
],
'layers': [
{
'geom': 'pie',
'stat': 'identity',
'mapping': {
'fill': 'name'
},
'tooltips': 'none',
'labels': {
'lines': ['@name']
},
'color': 'pen'
}
]
}""".trimIndent()
return parsePlotSpec(spec)
}

private fun example(
theme: String = "light",
flavor: String? = null,
background: String? = null
): MutableMap<String, Any> {
val themeSettings = listOf(
"'name': '$theme'",
background?.let { "'plot_background': {'fill': '$background', 'blank': false}" } ?: "",
flavor?.let { "'flavor': '$flavor'" } ?: ""
).filter(String::isNotEmpty).joinToString()

val spec = """{
"ggsize": { "width": 400, "height": 200 },
"theme": {
${background?.let { "'plot_background': {'fill': '$background', 'blank': false}" } ?: "" }
${if (background != null && flavor != null) "," else ""}
${flavor?.let { "'flavor': '$flavor'" } ?: ""}
},
"ggtitle": { "text": "theme=$theme, flavor=$flavor
point: \'brush\'+\'paper\'; line: \'pen\'" },
"theme": { $themeSettings },
"kind": "plot",
"layers": [
{
Expand Down
374 changes: 357 additions & 17 deletions docs/f-23c/named_system_colors.ipynb

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion future_changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ See: [example notebook](https://nbviewer.org/github/JetBrains/lets-plot/blob/mas
See: [example notebook](https://nbviewer.org/github/JetBrains/lets-plot/blob/master/docs/f-23c/geom_pie_stroke_and_spacers.ipynb).


- New named system colors: "pen", "paper", "brush".
- New named system colors: "pen", "paper", "brush";

`geom` parameter in `theme()` to specify new values for these colors via `element_geom()` function.

See: [example notebook](https://nbviewer.org/github/JetBrains/lets-plot/blob/master/docs/f-23c/named_system_colors.ipynb).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fun dynamicObjectToMap(o: dynamic): MutableMap<String, Any> {
var handleAnyNullable: (o: dynamic) -> Any? = {}

val handleObject: (o: dynamic) -> MutableMap<String, Any> = { o: dynamic ->
val map = HashMap<String, Any>()
val map = LinkedHashMap<String, Any>()
val entries = js("Object.entries(o)")
for (entry in entries) {
val key = entry[0] as String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface GeomContext {
val flipped: Boolean
val targetCollector: GeomTargetCollector
val annotations: Annotations?
val plotBackground: Color
val backgroundColor: Color

// ToDo: Just positional resolution along x or y-axis. Also, its now equal to "data resolution". No need to compute it in 'Aesthetics'.
fun getResolution(aes: Aes<Double>): Double
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class PieGeom : GeomBase(), WithWidth, WithHeight {
root.appendNodes(pieSectors.map(::buildSvgArcs))
if (spacerWidth > 0) {
root.appendNodes(
buildSvgSpacerLines(pieSectors, width = spacerWidth, color = spacerColor ?: ctx.plotBackground)
buildSvgSpacerLines(pieSectors, width = spacerWidth, color = spacerColor ?: ctx.backgroundColor)
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2023. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/

package org.jetbrains.letsPlot.core.plot.base.theme

import org.jetbrains.letsPlot.commons.values.Color

interface ColorTheme {
fun pen(): Color
fun brush(): Color
fun paper(): Color
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ interface Theme {
fun tooltips(): TooltipsTheme

fun geometries(geomKind: GeomKind): GeomTheme

fun colors(): ColorTheme
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ object BogusContext : GeomContext {
get() = error("Not available in a bogus geom context")
override val annotations: Annotations
get() = error("Not available in a bogus geom context")
override val plotBackground: Color
override val backgroundColor: Color
get() = error("Not available in a bogus geom context")

override fun getResolution(aes: Aes<Double>): Double {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object DemoAndTest {
coord = coord,
flippedAxis = flippedAxis,
targetCollector = targetCollector,
plotBackground = plotBackground
backgroundColor = plotBackground
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class GeomContextBuilder : ImmutableGeomContext.Builder {
private var geomTargetCollector: GeomTargetCollector = NullGeomTargetCollector()
private var fontFamilyRegistry: FontFamilyRegistry? = null
private var annotations: Annotations? = null
private var plotBackground: Color = Color.WHITE
private var backgroundColor: Color = Color.WHITE

constructor()

Expand All @@ -39,7 +39,7 @@ class GeomContextBuilder : ImmutableGeomContext.Builder {
aesBounds = ctx._aesBounds
geomTargetCollector = ctx.targetCollector
annotations = ctx.annotations
plotBackground = ctx.plotBackground
backgroundColor = ctx.backgroundColor
}

override fun flipped(flipped: Boolean): ImmutableGeomContext.Builder {
Expand Down Expand Up @@ -77,8 +77,8 @@ class GeomContextBuilder : ImmutableGeomContext.Builder {
return this
}

override fun plotBackground(color: Color): ImmutableGeomContext.Builder {
this.plotBackground = color
override fun backgroundColor(color: Color): ImmutableGeomContext.Builder {
this.backgroundColor = color
return this
}

Expand All @@ -95,7 +95,7 @@ class GeomContextBuilder : ImmutableGeomContext.Builder {
override val flipped: Boolean = b.flipped
override val targetCollector = b.geomTargetCollector
override val annotations = b.annotations
override val plotBackground = b.plotBackground
override val backgroundColor = b.backgroundColor

private val fontFamilyRegistry: FontFamilyRegistry? = b.fontFamilyRegistry

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interface ImmutableGeomContext : GeomContext {

fun annotations(annotations: Annotations?): Builder

fun plotBackground(color: Color): Builder
fun backgroundColor(color: Color): Builder

fun build(): ImmutableGeomContext
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2023. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/

package org.jetbrains.letsPlot.core.plot.builder.defaultTheme

import org.jetbrains.letsPlot.core.plot.base.theme.ColorTheme
import org.jetbrains.letsPlot.core.plot.builder.defaultTheme.values.ThemeOption.GEOM
import org.jetbrains.letsPlot.core.plot.builder.defaultTheme.values.ThemeOption.Geom.BRUSH
import org.jetbrains.letsPlot.core.plot.builder.defaultTheme.values.ThemeOption.Geom.PAPER
import org.jetbrains.letsPlot.core.plot.builder.defaultTheme.values.ThemeOption.Geom.PEN
import org.jetbrains.letsPlot.core.plot.builder.presentation.FontFamilyRegistry

internal class DefaultColorTheme(
options: Map<String, Any>,
fontFamilyRegistry: FontFamilyRegistry
) : ThemeValuesAccess(options, fontFamilyRegistry), ColorTheme {

private val geomElem = getElemValue(listOf(GEOM))

override fun pen() = getColor(geomElem, PEN)

override fun brush() = getColor(geomElem, BRUSH)

override fun paper() = getColor(geomElem, PAPER)
}
Loading