Skip to content

Instantly share code, notes, and snippets.

@lbustelo
Created August 19, 2015 16:13
Show Gist options
  • Save lbustelo/7063ca39bdb0974a6fb4 to your computer and use it in GitHub Desktop.
Save lbustelo/7063ca39bdb0974a6fb4 to your computer and use it in GitHub Desktop.
This is an example magic for ibm-et/spark-kernel
package com.ibm.spark.magic.builtin
import java.io.PrintStream
import com.ibm.spark.magic._
import com.ibm.spark.magic.dependencies._
import com.ibm.spark.utils.ArgumentParsingSupport
import com.ibm.spark.kernel.protocol.v5.MIMEType
import org.slf4j.LoggerFactory
/**
* Temporary magic to show chart as image
*/
class Plot extends CellMagic with IncludeKernelInterpreter
with IncludeOutputStream with ArgumentParsingSupport {
private lazy val printStream = new PrintStream(outputStream)
// TODO don't pollute interpreter with png val
private val png = "png123456789"
// Option to specify height of chart
private val height =
parser.accepts("height", "height of the generated chart")
.withOptionalArg().ofType(classOf[Int]).defaultsTo(300)
// Option to specify width of chart
private val width =
parser.accepts("width", "width of the generated chart")
.withOptionalArg().ofType(classOf[Int]).defaultsTo(400)
// Option for chart code
private val chart =
parser.accepts("chart", "code to generate the chart (no spaces!)")
.withRequiredArg().ofType(classOf[String])
/** Wraps code around chart to convert to Base64 String */
private def chartWrap(chart: String, width: Int, height: Int): String = {
val chartName = chart.trim
s"""
|val baos = new java.io.ByteArrayOutputStream()
|org.jfree.chart.ChartUtilities.writeChartAsPNG(baos, $chartName, $width, $height)
|val $png = javax.xml.bind.DatatypeConverter.printBase64Binary(baos.toByteArray)
""".stripMargin
}
/** Another DRY function to generate the plot */
private def interpretWrappedCode(code: String): CellMagicOutput = {
val (_, message) = kernelInterpreter.doQuietly {
kernelInterpreter.interpret(code)
}
if (message.isLeft)
kernelInterpreter.read(png) match {
case Some(value) =>
CellMagicOutput(MIMEType.ImagePng -> value.asInstanceOf[String])
case None =>
CellMagicOutput(MIMEType.PlainText -> "Error in plot magic!")
}
else
CellMagicOutput(MIMEType.PlainText -> message.right.get.toString)
}
/**
* Plots a chart. Plot magic declaration takes code to plot.
*
* Usage: %plot [width=<int>] [height=<int>] chart=<code>
*
* Example:
* %plot --width=100 --height=100 --chart=ChartFactory.createPieChart("name",data)
*
* Note: chart parameter must be final parameter
* @param code Plot arguments
* @return Base64 String representing the plot
*/
override def execute(code: String): CellMagicOutput = {
parseArgs(code.split("\n").head) // Assume first line is arguments
has(chart) match {
case false =>
printHelp(
printStream, """%%Plot --chart=<string> --height=<int> --width=<int>"""
)
CellMagicOutput()
case true =>
interpretWrappedCode(chartWrap(chart.get, width.get, height.get))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment