1
1
package org.jetbrains.kotlinx.dataframe.explainer
2
2
3
- import com.beust.klaxon.JsonObject
4
3
import org.jetbrains.kotlinx.dataframe.AnyCol
5
4
import org.jetbrains.kotlinx.dataframe.AnyFrame
6
5
import org.jetbrains.kotlinx.dataframe.DataFrame
@@ -22,7 +21,6 @@ import org.jetbrains.kotlinx.dataframe.api.Update
22
21
import org.jetbrains.kotlinx.dataframe.api.format
23
22
import org.jetbrains.kotlinx.dataframe.api.frames
24
23
import org.jetbrains.kotlinx.dataframe.api.into
25
- import org.jetbrains.kotlinx.dataframe.api.print
26
24
import org.jetbrains.kotlinx.dataframe.api.toDataFrame
27
25
import org.jetbrains.kotlinx.dataframe.api.values
28
26
import org.jetbrains.kotlinx.dataframe.api.where
@@ -35,71 +33,6 @@ import org.jetbrains.kotlinx.dataframe.io.tableInSessionId
35
33
import org.jetbrains.kotlinx.dataframe.io.toHTML
36
34
import java.io.File
37
35
38
- private fun convertToHTML (dataframeLike : Any ): DataFrameHtmlData {
39
- fun DataFrame <* >.toHTML () = toHTML(DisplayConfiguration (), getFooter = { " " })
40
- fun FormattedFrame <* >.toHTML1 () = toHTML(DisplayConfiguration ())
41
-
42
- return when (dataframeLike) {
43
- is Pivot <* > -> dataframeLike.frames().toDataFrame().toHTML()
44
- is ReducedPivot <* > -> dataframeLike.values().toDataFrame().toHTML()
45
- is PivotGroupBy <* > -> dataframeLike.frames().toHTML()
46
- is ReducedPivotGroupBy <* > -> dataframeLike.values().toHTML()
47
- is SplitWithTransform <* , * , * > -> dataframeLike.into().toHTML()
48
- is Merge <* , * , * > -> dataframeLike.into(" merged" ).toHTML()
49
- is Gather <* , * , * , * > -> dataframeLike.into(" key" , " value" ).toHTML()
50
- is Update <* , * > -> dataframeLike.df.let {
51
- var it = it.format(dataframeLike.columns as ColumnsSelectionDsl <Any ?>.(it: ColumnsSelectionDsl <Any ?>) -> ColumnSet <* >)
52
- if (dataframeLike.filter != null ) {
53
- it = it.where(dataframeLike.filter as RowValueFilter <Any ?, Any ?>)
54
- }
55
- it.with {
56
- background(rgb(152 , 251 , 152 ))
57
- }
58
- }
59
- .toHTML1()
60
- is Convert <* , * > -> DataFrameHtmlData (body = " <p>${dataframeLike::class } </p>" )
61
- is FormattedFrame <* > -> dataframeLike.toHTML1()
62
- is GroupBy <* , * > -> dataframeLike.toDataFrame().toHTML()
63
- is AnyFrame -> dataframeLike.toHTML()
64
- is AnyCol -> dataframeLike.toDataFrame().toHTML()
65
- is DataRow <* > -> dataframeLike.toDataFrame().toHTML()
66
- is Split <* , * > -> dataframeLike.toDataFrame().toHTML()
67
- // is MoveClause<*, *>-> null
68
- // is RenameClause<*, *> -> null
69
- // is ReplaceClause<*, *> -> null
70
- // is GroupClause<*, *> -> null
71
- // is InsertClause<*> -> null
72
- // is FormatClause<*, *> -> null
73
- else -> throw IllegalArgumentException (" Unsupported type: ${dataframeLike::class } " )
74
- }
75
- }
76
-
77
- private fun convertToDescription (dataframeLike : Any ): String {
78
- return when (dataframeLike) {
79
- is AnyFrame -> dataframeLike.let { " DataFrame: rowsCount = ${it.rowsCount()} , columnsCount = ${it.columnsCount()} " }
80
- is Pivot <* > -> " Pivot"
81
- is ReducedPivot <* > -> " ReducedPivot"
82
- is PivotGroupBy <* > -> " PivotGroupBy"
83
- is ReducedPivotGroupBy <* > -> " ReducedPivotGroupBy"
84
- is SplitWithTransform <* , * , * > -> " SplitWithTransform"
85
- is Split <* , * > -> " Split"
86
- // is MoveClause<*, *> -> "Move"
87
- // is RenameClause<*, *> -> "Rename"
88
- // is ReplaceClause<*, *> -> "Replace"
89
- // is GroupClause<*, *> -> "Group"
90
- // is InsertClause<*> -> "Insert"
91
- // is FormatClause<*, *> -> "Format"
92
- is Merge <* , * , * > -> " Merge"
93
- is Gather <* , * , * , * > -> " Gather"
94
- is Update <* , * > -> " Update"
95
- is Convert <* , * > -> " Convert"
96
- is FormattedFrame <* > -> " FormattedFrame"
97
- is GroupBy <* , * > -> " GroupBy"
98
- is DataRow <* > -> " DataRow"
99
- else -> " TODO"
100
- }.escapeHtmlForIFrame()
101
- }
102
-
103
36
annotation class TransformDataFrameExpressions
104
37
105
38
object PluginCallback {
@@ -122,6 +55,7 @@ object PluginCallback {
122
55
sessionId = 0
123
56
tableInSessionId = 0
124
57
var output = DataFrameHtmlData .tableDefinitions() + DataFrameHtmlData (
58
+ // copy writerside stlyles
125
59
style = """
126
60
body {
127
61
font-family: "JetBrains Mono",SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;
@@ -150,13 +84,13 @@ object PluginCallback {
150
84
// make copy to avoid concurrent modification exception
151
85
val statements = expressionsByStatement.toMap()
152
86
when (statements.size) {
153
- 0 -> TODO (" wtf " )
87
+ 0 -> TODO (" function doesn't have any dataframe expression " )
154
88
1 -> {
155
- output + = expressionOutputs (statements.values.single(), open = false )
89
+ output + = statementOutput (statements.values.single())
156
90
}
157
91
else -> {
158
92
statements.forEach { (index, expressions) ->
159
- var details: DataFrameHtmlData = expressionOutputs (expressions, open = true )
93
+ var details: DataFrameHtmlData = statementOutput (expressions)
160
94
161
95
details = details.copy(
162
96
body =
@@ -185,12 +119,9 @@ object PluginCallback {
185
119
output.writeHTML(File (destination, " $name .html" ))
186
120
}
187
121
188
- private fun expressionOutputs (
122
+ private fun statementOutput (
189
123
expressions : List <Expression >,
190
- open : Boolean ,
191
124
): DataFrameHtmlData {
192
- // val attribute = if (open) " open" else ""
193
- val attribute = " "
194
125
var data = DataFrameHtmlData ()
195
126
if (expressions.size < 2 ) error(" Sample without output or input (i.e. function returns some value)" )
196
127
for ((i, expression) in expressions.withIndex()) {
@@ -199,7 +130,7 @@ object PluginCallback {
199
130
val table = convertToHTML(expression.df)
200
131
val description = table.copy(
201
132
body = """
202
- <details$attribute >
133
+ <details>
203
134
<summary>Input ${convertToDescription(expression.df)} </summary>
204
135
${table.body}
205
136
</details>
@@ -212,7 +143,7 @@ object PluginCallback {
212
143
val table = convertToHTML(expression.df)
213
144
val description = table.copy(
214
145
body = """
215
- <details$attribute >
146
+ <details>
216
147
<summary>Output ${convertToDescription(expression.df)} </summary>
217
148
${table.body}
218
149
</details>
@@ -244,41 +175,6 @@ object PluginCallback {
244
175
val element = Expression (source, containingClassFqName, containingFunName, df)
245
176
list?.plus(element) ? : listOf (element)
246
177
}
247
- // strings.add(string)
248
- // names.add(name)
249
- // Can be called with the same name multiple times, need to aggregate samples by function name somehow?
250
- // save schema
251
- val path = " $containingClassFqName .$containingFunName .html"
252
- // names.compute(path) { }
253
- // dfs.add(path)
254
- if (df is AnyFrame ) {
255
- println (source)
256
- // df.print()
257
- println (id)
258
- println (receiverId)
259
- } else {
260
- println (df::class )
261
- }
262
- File (" build/out" ).let {
263
- val json = JsonObject (
264
- mapOf (
265
- " string" to source,
266
- " name" to name,
267
- " path" to path,
268
- " id" to id,
269
- " receiverId" to receiverId,
270
- )
271
- ).toJsonString()
272
- it.appendText(json)
273
- it.appendText(" ,\n " )
274
- }
275
- println (path)
276
- if (df is AnyFrame ) {
277
- df.print ()
278
- } else {
279
- println (df::class )
280
- }
281
- // convertToHTML(df).writeHTML(File("build/dataframes/$path"))
282
178
}
283
179
284
180
@Suppress(" unused" )
@@ -296,6 +192,71 @@ object PluginCallback {
296
192
}
297
193
}
298
194
195
+ private fun convertToHTML (dataframeLike : Any ): DataFrameHtmlData {
196
+ fun DataFrame <* >.toHTML () = toHTML(DisplayConfiguration (), getFooter = { " " })
197
+ fun FormattedFrame <* >.toHTML1 () = toHTML(DisplayConfiguration ())
198
+
199
+ return when (dataframeLike) {
200
+ is Pivot <* > -> dataframeLike.frames().toDataFrame().toHTML()
201
+ is ReducedPivot <* > -> dataframeLike.values().toDataFrame().toHTML()
202
+ is PivotGroupBy <* > -> dataframeLike.frames().toHTML()
203
+ is ReducedPivotGroupBy <* > -> dataframeLike.values().toHTML()
204
+ is SplitWithTransform <* , * , * > -> dataframeLike.into().toHTML()
205
+ is Merge <* , * , * > -> dataframeLike.into(" merged" ).toHTML()
206
+ is Gather <* , * , * , * > -> dataframeLike.into(" key" , " value" ).toHTML()
207
+ is Update <* , * > -> dataframeLike.df.let {
208
+ var it = it.format(dataframeLike.columns as ColumnsSelectionDsl <Any ?>.(it: ColumnsSelectionDsl <Any ?>) -> ColumnSet <* >)
209
+ if (dataframeLike.filter != null ) {
210
+ it = it.where(dataframeLike.filter as RowValueFilter <Any ?, Any ?>)
211
+ }
212
+ it.with {
213
+ background(rgb(152 , 251 , 152 ))
214
+ }
215
+ }
216
+ .toHTML1()
217
+ is Convert <* , * > -> DataFrameHtmlData (body = " <p>${dataframeLike::class } </p>" )
218
+ is FormattedFrame <* > -> dataframeLike.toHTML1()
219
+ is GroupBy <* , * > -> dataframeLike.toDataFrame().toHTML()
220
+ is AnyFrame -> dataframeLike.toHTML()
221
+ is AnyCol -> dataframeLike.toDataFrame().toHTML()
222
+ is DataRow <* > -> dataframeLike.toDataFrame().toHTML()
223
+ is Split <* , * > -> dataframeLike.toDataFrame().toHTML()
224
+ // is MoveClause<*, *>-> null
225
+ // is RenameClause<*, *> -> null
226
+ // is ReplaceClause<*, *> -> null
227
+ // is GroupClause<*, *> -> null
228
+ // is InsertClause<*> -> null
229
+ // is FormatClause<*, *> -> null
230
+ else -> throw IllegalArgumentException (" Unsupported type: ${dataframeLike::class } " )
231
+ }
232
+ }
233
+
234
+ private fun convertToDescription (dataframeLike : Any ): String {
235
+ return when (dataframeLike) {
236
+ is AnyFrame -> dataframeLike.let { " DataFrame: rowsCount = ${it.rowsCount()} , columnsCount = ${it.columnsCount()} " }
237
+ is Pivot <* > -> " Pivot"
238
+ is ReducedPivot <* > -> " ReducedPivot"
239
+ is PivotGroupBy <* > -> " PivotGroupBy"
240
+ is ReducedPivotGroupBy <* > -> " ReducedPivotGroupBy"
241
+ is SplitWithTransform <* , * , * > -> " SplitWithTransform"
242
+ is Split <* , * > -> " Split"
243
+ // is MoveClause<*, *> -> "Move"
244
+ // is RenameClause<*, *> -> "Rename"
245
+ // is ReplaceClause<*, *> -> "Replace"
246
+ // is GroupClause<*, *> -> "Group"
247
+ // is InsertClause<*> -> "Insert"
248
+ // is FormatClause<*, *> -> "Format"
249
+ is Merge <* , * , * > -> " Merge"
250
+ is Gather <* , * , * , * > -> " Gather"
251
+ is Update <* , * > -> " Update"
252
+ is Convert <* , * > -> " Convert"
253
+ is FormattedFrame <* > -> " FormattedFrame"
254
+ is GroupBy <* , * > -> " GroupBy"
255
+ is DataRow <* > -> " DataRow"
256
+ else -> throw IllegalArgumentException (" Unsupported type: ${dataframeLike::class } " )
257
+ }.escapeHtmlForIFrame()
258
+ }
259
+
299
260
internal fun String.escapeHtmlForIFrame (): String {
300
261
val str = this
301
262
return buildString {
0 commit comments