Skip to content
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
52 changes: 32 additions & 20 deletions almond/src/main/scala/plotly/Almond.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package plotly

import java.lang.{Boolean => JBoolean, Double => JDouble, Integer => JInt}

import almond.interpreter.api.OutputHandler
import almond.interpreter.api.{DisplayData, OutputHandler}

import scala.util.Random
import plotly.element._
Expand All @@ -23,7 +23,7 @@ object Almond {
s"""define('plotly', function(require, exports, module) {
| ${Plotly.plotlyMinJs}
|});
"""
""".stripMargin
else
"""require.config({
| paths: {
Expand All @@ -50,25 +50,48 @@ object Almond {
</script>
"""

Internal.initialized = true

publish.html(html)
}

def plotJs(
div: String,
data: Seq[Trace],
layout: Layout
layout: Layout,
div: String = ""
)(implicit
publish: OutputHandler
): Unit = {
): String = {

val baseJs = Plotly.jsSnippet(div, data, layout)
val (div0, divPart) =
if (div.isEmpty) {
val d = randomDiv()
(d, s"""<div class="chart" id="$d"></div>""")
} else
(div, "")

val baseJs = Plotly.jsSnippet(div0, data, layout)
val json = Plotly.jsonSnippet(data, layout)

val js =
s"""requirejs(["plotly"], function(Plotly) {
s"""require('plotly', function(Plotly) {
| $baseJs
|});
""".stripMargin
publish.js(js)

val data0 = DisplayData(
data = Map(
"text/html" ->
s"""$divPart
|<script>$js</script>
""".stripMargin,
"application/vnd.plotly.v1+json" -> json
)
)

publish.display(data0)

div0
}

def randomDiv() = "plot-" + math.abs(Random.nextInt().toLong)
Expand All @@ -89,18 +112,7 @@ object Almond {
}
}

val div0 =
if (div.isEmpty)
randomDiv()
else
div

if (div.isEmpty)
publish.html(s"""<div class="chart" id="$div0"></div>""")

plotJs(div0, data, layout)

div0
plotJs(data, layout)
}

implicit class DataOps(val data: Trace) extends AnyVal {
Expand Down
28 changes: 27 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,33 @@ lazy val render = crossProject(JVMPlatform, JSPlatform)
libraryDependencies += Deps.argonautShapeless.value
)
.jvmSettings(
libraryDependencies += WebDeps.plotlyJs
libraryDependencies ++= Seq(
WebDeps.plotlyJs,
Deps.scalaTest % "test"
),
resourceGenerators.in(Compile) += Def.task {
import sys.process._

val dir = classDirectory.in(Compile).value / "plotly"
val ver = version.value

val f = dir / "plotly-scala.properties"
dir.mkdirs()

val p = new java.util.Properties

p.setProperty("plotly-js-version", WebDeps.Versions.plotlyJs)
p.setProperty("version", ver)
p.setProperty("commit-hash", Seq("git", "rev-parse", "HEAD").!!.trim)

val w = new java.io.FileOutputStream(f)
p.store(w, "plotly-scala properties")
w.close()

state.value.log.info(s"Wrote $f")

Seq(f)
}
)
.jsSettings(
libraryDependencies += Deps.scalajsDom.value
Expand Down
6 changes: 5 additions & 1 deletion project/WebDeps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import sbt._

object WebDeps {

object Versions {
def plotlyJs = "1.41.3"
}

def bootstrap = "org.webjars.bower" % "bootstrap" % "3.3.6"
def jquery = "org.webjars.bower" % "jquery" % "2.2.4"
def plotlyJs = "org.webjars.bower" % "plotly.js" % "1.41.3"
def plotlyJs = "org.webjars.bower" % "plotly.js" % Versions.plotlyJs
def prism = "org.webjars.bower" % "prism" % "1.5.0"

}
5 changes: 3 additions & 2 deletions render/js/src/main/scala/plotly/Plotly.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import argonaut.Argonaut._
import argonaut.{Json, PrettyParams}
import plotly.Codecs._
import plotly.element.Color
import plotly.internals.BetterPrinter
import plotly.layout._

import scala.scalajs.js
Expand All @@ -14,10 +15,10 @@ import scala.scalajs.js.JSON

object Plotly {

private val printer = PrettyParams.nospace.copy(dropNullKeys = true)
private val printer = BetterPrinter(PrettyParams.nospace.copy(dropNullKeys = true))
private def stripNulls(json: Json): js.Any = {
// Remove empty objects
JSON.parse(printer.pretty(json))
JSON.parse(printer.render(json))
}

def plot(div: String, data: Seq[Trace], layout: Layout): Unit = {
Expand Down
22 changes: 17 additions & 5 deletions render/jvm/src/main/scala/plotly/Plotly.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,24 @@ import java.lang.{Boolean => JBoolean, Double => JDouble, Integer => JInt}
import java.nio.file.Files

import argonaut.Argonaut._
import argonaut.PrettyParams
import argonaut.{Json, PrettyParams}
import plotly.internals.{BetterPrinter, Properties}

import scala.annotation.tailrec

object Plotly {

private val printer = PrettyParams.nospace.copy(dropNullKeys = true)
private val printer = BetterPrinter(PrettyParams.nospace.copy(dropNullKeys = true))

def jsonSnippet(data: Seq[Trace], layout: Layout): String = {

val json = Json.obj(
"data" -> data.toList.asJson,
"layout" -> layout.asJson
)

printer.render(json)
}

def jsSnippet(div: String, data: Seq[Trace], layout: Layout): String = {

Expand All @@ -25,15 +36,15 @@ object Plotly {

for ((d, idx) <- data.zipWithIndex) {
b ++= s" var data$idx = "
b ++= printer.pretty(d.asJson)
b ++= printer.render(d.asJson)
b ++= ";\n"
}

b ++= "\n "
b ++= data.indices.map(idx => s"data$idx").mkString("var data = [", ", ", "];")
b ++= "\n"
b ++= " var layout = "
b ++= printer.pretty(layout.asJson)
b ++= printer.render(layout.asJson)
b ++= ";\n\n Plotly.plot('"
b ++= div.replaceAll("'", "\\'")
b ++= "', data, layout);\n"
Expand All @@ -57,7 +68,8 @@ object Plotly {
buffer.toByteArray
}

val plotlyVersion = "1.12.0" // FIXME Get from build.sbt
def plotlyVersion: String =
Properties.plotlyJsVersion

def plotlyMinJs: String = {
var is: InputStream = null
Expand Down
26 changes: 26 additions & 0 deletions render/jvm/src/main/scala/plotly/internals/Properties.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package plotly.internals

import java.util.{Properties => JProperties}

object Properties {

private lazy val props = {
val p = new JProperties
try {
p.load(
getClass
.getClassLoader
.getResourceAsStream("plotly/plotly-scala.properties")
)
}
catch {
case _: NullPointerException =>
}
p
}

lazy val plotlyJsVersion = props.getProperty("plotly-js-version")
lazy val version = props.getProperty("version")
lazy val commitHash = props.getProperty("commit-hash")

}
11 changes: 11 additions & 0 deletions render/jvm/src/test/scala/plotly/ResourceTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package plotly

import org.scalatest.PropSpec

class ResourceTests extends PropSpec {

property("plotly.min.js must be found in resources") {
assert(Plotly.plotlyMinJs.nonEmpty)
}

}
Loading