Skip to content

Commit 3db46cc

Browse files
committed
Use new kernel API to add horizontal scrolling in Kotlin Notebook
1 parent b24265b commit 3db46cc

File tree

7 files changed

+26
-50
lines changed

7 files changed

+26
-50
lines changed

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/format.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import org.jetbrains.kotlinx.dataframe.impl.api.formatImpl
1313
import org.jetbrains.kotlinx.dataframe.impl.api.linearGradient
1414
import org.jetbrains.kotlinx.dataframe.impl.columns.toColumns
1515
import org.jetbrains.kotlinx.dataframe.io.DisplayConfiguration
16-
import org.jetbrains.kotlinx.dataframe.io.HtmlData
1716
import org.jetbrains.kotlinx.dataframe.io.toHTML
17+
import org.jetbrains.kotlinx.jupyter.api.HtmlData
1818
import kotlin.reflect.KProperty
1919

2020
// region DataFrame

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ import org.jetbrains.kotlinx.dataframe.jupyter.RenderedContent
2121
import org.jetbrains.kotlinx.dataframe.name
2222
import org.jetbrains.kotlinx.dataframe.nrow
2323
import org.jetbrains.kotlinx.dataframe.size
24-
import org.jetbrains.kotlinx.jupyter.api.HTML
25-
import org.jetbrains.kotlinx.jupyter.api.MimeTypedResult
24+
import org.jetbrains.kotlinx.jupyter.api.HtmlData
2625
import java.io.InputStreamReader
2726
import java.net.URL
2827
import java.util.LinkedList
@@ -154,41 +153,7 @@ internal fun AnyFrame.toHtmlData(
154153
}
155154
val body = getResourceText("/table.html", "ID" to rootId)
156155
val script = scripts.joinToString("\n") + "\n" + getResourceText("/renderTable.js", "___ID___" to rootId)
157-
return HtmlData("", body, script, configuration.useDarkColorScheme)
158-
}
159-
160-
public data class HtmlData(val style: String, val body: String, val script: String, val useDarkColorScheme: Boolean) {
161-
override fun toString(): String = """
162-
<html>
163-
<head>
164-
<style type="text/css">
165-
$style
166-
</style>
167-
</head>
168-
<body>
169-
<div${darkSchemeAttribute()}>
170-
$body
171-
</div>
172-
</body>
173-
<script>
174-
$script
175-
</script>
176-
</html>
177-
""".trimIndent()
178-
179-
private fun darkSchemeAttribute(): String {
180-
return if (useDarkColorScheme) " class=\"dataframe_dark\"" else ""
181-
}
182-
183-
public fun toJupyter(): MimeTypedResult = HTML(toString())
184-
185-
public operator fun plus(other: HtmlData): HtmlData =
186-
HtmlData(
187-
style + "\n" + other.style,
188-
body + "\n" + other.body,
189-
script + "\n" + other.script,
190-
useDarkColorScheme || other.useDarkColorScheme
191-
)
156+
return HtmlData("", body, script)
192157
}
193158

194159
internal fun HtmlData.print() = println(this)
@@ -198,7 +163,6 @@ internal fun initHtml(includeJs: Boolean = true, includeCss: Boolean = true, use
198163
style = if (includeCss) getResources("/table.css") else "",
199164
script = if (includeJs) getResourceText("/init.js") else "",
200165
body = "",
201-
useDarkColorScheme = useDarkColorScheme,
202166
)
203167

204168
public fun <T> DataFrame<T>.html(): String = toHTML(extraHtml = initHtml()).toString()
@@ -212,12 +176,19 @@ public fun <T> DataFrame<T>.toHTML(
212176
val limit = configuration.rowsLimit
213177

214178
val footer = getFooter(this)
215-
val bodyFooter = if (limit < nrow) {
216-
"<p>... showing only top $limit of $nrow rows</p><p>$footer</p>"
217-
} else "<p>$footer</p>"
179+
val bodyFooter = buildString {
180+
val openPTag = "<p class=\"dataframe_description\">"
181+
if (limit < nrow) {
182+
append(openPTag)
183+
append("... showing only top $limit of $nrow rows</p>")
184+
}
185+
append(openPTag)
186+
append(footer)
187+
append("</p>")
188+
}
218189

219190
val tableHtml = toHtmlData(configuration, cellRenderer)
220-
val html = tableHtml + HtmlData("", bodyFooter, "", configuration.useDarkColorScheme)
191+
val html = tableHtml + HtmlData("", bodyFooter, "")
221192

222193
return if (extraHtml != null) extraHtml + html else html
223194
}
@@ -228,7 +199,7 @@ public data class DisplayConfiguration(
228199
var cellFormatter: RowColFormatter<*, *>? = null,
229200
var decimalFormat: RendererDecimalFormat = RendererDecimalFormat.DEFAULT,
230201
var isolatedOutputs: Boolean = flagFromEnv("LETS_PLOT_HTML_ISOLATED_FRAME"),
231-
internal val localTesting: Boolean = flagFromEnv("KOTLIN_DATAFRAME_LOCAL_TESTING"),
202+
internal val localTesting: Boolean = true, // flagFromEnv("KOTLIN_DATAFRAME_LOCAL_TESTING"),
232203
var useDarkColorScheme: Boolean = false,
233204
) {
234205
public companion object {

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/jupyter/Integration.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ import org.jetbrains.kotlinx.dataframe.dataTypes.IFRAME
3535
import org.jetbrains.kotlinx.dataframe.dataTypes.IMG
3636
import org.jetbrains.kotlinx.dataframe.impl.createStarProjectedType
3737
import org.jetbrains.kotlinx.dataframe.impl.renderType
38-
import org.jetbrains.kotlinx.dataframe.io.HtmlData
3938
import org.jetbrains.kotlinx.jupyter.api.HTML
39+
import org.jetbrains.kotlinx.jupyter.api.HtmlData
4040
import org.jetbrains.kotlinx.jupyter.api.KotlinKernelHost
4141
import org.jetbrains.kotlinx.jupyter.api.VariableName
4242
import org.jetbrains.kotlinx.jupyter.api.declare
@@ -76,7 +76,7 @@ internal class Integration : JupyterIntegration() {
7676
}
7777

7878
with(JupyterHtmlRenderer(config.display, this)) {
79-
render<HtmlData> { it.toJupyter() }
79+
render<HtmlData> { notebook.renderHtmlAsIFrame(it) }
8080
render<AnyRow>({ it.toDataFrame() }, { "DataRow: index = ${it.index()}, columnsCount = ${it.columnsCount()}" })
8181
render<ColumnGroup<*>>({ it.asDataFrame() }, { """ColumnGroup: name = "${it.name}", rowsCount = ${it.rowsCount()}, columnsCount = ${it.columnsCount()}""" })
8282
render<AnyCol>({ dataFrameOf(it) }, { """DataColumn: name = "${it.name}", type = ${renderType(it.type())}, size = ${it.size()}""" })

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/jupyter/JupyterHtmlRenderer.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ internal inline fun <reified T : Any> JupyterHtmlRenderer.render(
1919
val contextRenderer = JupyterCellRenderer(this.notebook, host)
2020
val reifiedDisplayConfiguration = value.modifyConfig(display)
2121
val footer = getFooter(value)
22-
getDf(value).toHTML(
22+
val html = getDf(value).toHTML(
2323
reifiedDisplayConfiguration,
2424
extraHtml = initHtml(
2525
includeJs = reifiedDisplayConfiguration.isolatedOutputs,
@@ -28,5 +28,6 @@ internal inline fun <reified T : Any> JupyterHtmlRenderer.render(
2828
),
2929
contextRenderer
3030
) { footer }
31-
.toJupyter()
31+
32+
notebook.renderHtmlAsIFrame(html)
3233
}

core/src/main/resources/table.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
--link-hover: #00688e;
3131
}
3232

33+
p.dataframe_description {
34+
color: var(--text-color-dark);
35+
}
36+
3337
table.dataframe {
3438
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
3539
font-size: 12px;

core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/jupyter/RenderingTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class RenderingTests : JupyterReplTestCase() {
7070
val htmlDark = execSimpleDf()
7171

7272
r1 shouldBe 1
73-
val darkClassAttribute = """class="dataframe_dark""""
73+
val darkClassAttribute = """theme='dark'"""
7474
htmlLight shouldNotContain darkClassAttribute
7575
htmlDark shouldContain darkClassAttribute
7676
}

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[versions]
22
ksp = "1.7.20-1.0.8"
3-
kotlinJupyter = "0.11.0-176"
3+
kotlinJupyter = "0.11.0-180-1"
44
ktlint = "3.4.5"
55
kotlin = "1.7.20"
66
dokka = "1.6.20"

0 commit comments

Comments
 (0)