1

I am playing around with these two awesome projects ochrons/scalajs-spa-tutorial and with vmunier/play-with-scalajs-example, but it is a struggle due to my lack of experience with javascript and web programming in general.

I am trying to use chart.js in my scala.js program. I have an "uncaught typeerror undefined is not a function" here :

val t = new JSChart(ctx).Bar(ChartData(Seq("A", "B", "C"), Seq(ChartDataset(Seq(1, 2, 3), "Data1"))))

The code :

object ScalaJSExample extends js.JSApp {
 def main(): Unit = {
   //dom.document.getElementById("page-wrapper").asInstanceOf[html.Div].innerHTML = "GoT"
}

@JSExport
def test(canvas: html.Canvas): Unit = {
  val ctx = canvas.getContext("2d")
  val t = new JSChart(ctx).Bar(ChartData(Seq("A", "B", "C"), Seq(ChartDataset(Seq(1, 2, 3), "Data1"))))
  t.build
}

trait ChartDataset extends js.Object {
  def label: String = js.native
  def fillColor: String = js.native
  def strokeColor: String = js.native
  def data: js.Array[Double] = js.native
}

object ChartDataset {
  def apply(data: Seq[Double], label: String, fillColor: String = "#8080FF", strokeColor: String = "#404080"): ChartDataset = {
    js.Dynamic.literal(
      data = data.toJSArray,
      label = label,
      fillColor = fillColor,
      strokeColor = strokeColor
    ).asInstanceOf[ChartDataset]
  }
}

trait ChartData extends js.Object {
  def labels: js.Array[String] = js.native
  def datasets: js.Array[ChartDataset] = js.native
}

object ChartData {
  def apply(labels: Seq[String], datasets: Seq[ChartDataset]): ChartData = {
    js.Dynamic.literal(
      labels = labels.toJSArray,
      datasets = datasets.toJSArray
    ).asInstanceOf[ChartData]
  }
}

// define a class to access the Chart.js component
@JSName("Chart")
class JSChart(ctx: js.Dynamic) extends js.Object {
  // create different kinds of charts
   def Line(data: ChartData): js.Dynamic = js.native
   def Bar(data: ChartData): js.Dynamic = js.native
   }
}

My view :

 <div id="page-wrapper">
   <canvas style="display: block" id="canvas" width="255" height="255"/>
 </div>
...
@playscalajs.html.scripts("scalajsClient")
<script>
    example.ScalaJSExample().test(document.getElementById('canvas'));
</script>
...

What do I miss?

Update :

As srjd suggest, I didn't include chart.js. Now I am trying to do so. I change my build.sbt to add a jsDependencies on the webjar chart.js. But I have this error. Any idea why?

$sbt reload
error: No implicit for    Append.Value[Seq[org.scalajs.sbtplugin.AbstractJSDep], sbt.ModuleID] found,
  so sbt.ModuleID cannot be appended to    Seq[org.scalajs.sbtplugin.AbstractJSDep]
  jsDependencies += "org.webjars" % "chartjs"  % "1.0.1",

Build.sbt

import org.scalajs.sbtplugin.ScalaJSPlugin
import org.scalajs.sbtplugin.cross.CrossType
import play.PlayScala
import playscalajs.ScalaJSPlay
import sbt.Project.projectToRef

lazy val clients = Seq(scalajsClient)
lazy val scalaV = "2.11.6"

lazy val playServer = (project in file("play-server")).settings(
  scalaVersion := scalaV,
  scalaJSProjects := clients,
  pipelineStages := Seq(scalaJSProd, gzip),
  libraryDependencies ++= Seq(
  "com.vmunier" %% "play-scalajs-scripts" % "0.2.1",
  "org.webjars" % "jquery" % "1.11.1",
  "org.webjars" % "chartjs"  % "1.0.1"
 )
).enablePlugins(PlayScala).
  aggregate(clients.map(projectToRef): _*).
  dependsOn(sharedJvm)

lazy val scalajsClient = (project in file("scalajs-client")).settings(
  scalaVersion := scalaV,
  persistLauncher := true,
  persistLauncher in Test := false,
  sourceMapsDirectories += sharedJs.base / "..",
  unmanagedSourceDirectories in Compile := Seq((scalaSource in    Compile).value),
  jsDependencies += "org.webjars" % "chartjs"  % "1.0.1",
  libraryDependencies ++= Seq(
   "org.scala-js" %%% "scalajs-dom" % "0.8.0"
  )
).enablePlugins(ScalaJSPlugin, ScalaJSPlay).
  dependsOn(sharedJs)

lazy val shared = (crossProject.crossType(CrossType.Pure) in   file("shared")).
  settings(scalaVersion := scalaV).
  jsConfigure(_ enablePlugins ScalaJSPlay).
  jsSettings(sourceMapsBase := baseDirectory.value / "..")

lazy val sharedJvm = shared.jvm
lazy val sharedJs = shared.js


onLoad in Global := (Command.process("project playServer", _: State)) compose (onLoad in Global).value
6
  • Did you include the Chart.js library anywhere in your Web page? If not, you'd better do that ;-) Commented May 2, 2015 at 21:13
  • I didn't. I am trying to figure how to include it. For now I have in my build.sbt "org.webjars" % "chartjs" % "1.0.1" and that's all. Commented May 2, 2015 at 21:46
  • I saw on your tuto that I need to use jsDependencies and not libraryDependencies. But when I do I have "error: No implicit for Append.Value[Seq[org.scalajs.sbtplugin.AbstractJSDep], sbt.ModuleID] found, so sbt.ModuleID cannot be appended to Seq[org.scalajs.sbtplugin.AbstractJSDep] jsDependencies += "org.webjars" % "chartjs" % "1.0.1"" An idea why? Commented May 2, 2015 at 22:11
  • 1
    You're missing a trailing / "chart.js" for jsDependencies, or something similar. Commented May 3, 2015 at 4:02
  • That was it! Thanks jsDependencies += "org.webjars" % "chartjs" % "1.0.1" / "Chart.js" Commented May 3, 2015 at 7:18

1 Answer 1

2

Before (wrong) :

jsDependencies += "org.webjars" % "chartjs"  % "1.0.1"

After (good) :

jsDependencies += "org.webjars" % "chartjs"  % "1.0.1" / "Chart.js"

My all build.sbt :

import org.scalajs.sbtplugin.ScalaJSPlugin
import org.scalajs.sbtplugin.cross.CrossType
import play.PlayScala
import playscalajs.ScalaJSPlay
import sbt.Project.projectToRef

lazy val clients = Seq(scalajsClient)
lazy val scalaV = "2.11.6"

lazy val playServer = (project in file("play-server")).settings(
  scalaVersion := scalaV,
  scalaJSProjects := clients,
  pipelineStages := Seq(scalaJSProd, gzip),
  libraryDependencies ++= Seq(
    "com.vmunier" %% "play-scalajs-scripts" % "0.2.1",
    "org.webjars" % "jquery" % "1.11.1",
    "org.webjars" % "chartjs"  % "1.0.1"
  )
).enablePlugins(PlayScala).
  aggregate(clients.map(projectToRef): _*).
  dependsOn(sharedJvm)

lazy val scalajsClient = (project in file("scalajs-client")).settings(
  scalaVersion := scalaV,
  persistLauncher := true,
  persistLauncher in Test := false,
  sourceMapsDirectories += sharedJs.base / "..",
  unmanagedSourceDirectories in Compile := Seq((scalaSource in    Compile).value),
  jsDependencies += "org.webjars" % "chartjs"  % "1.0.1" / "Chart.js",
  skip in packageJSDependencies := false,
  libraryDependencies ++= Seq(
    "org.scala-js" %%% "scalajs-dom" % "0.8.0"
  )
).enablePlugins(ScalaJSPlugin, ScalaJSPlay).
  dependsOn(sharedJs)

lazy val shared = (crossProject.crossType(CrossType.Pure) in file("shared")).
  settings(scalaVersion := scalaV).
  jsConfigure(_ enablePlugins ScalaJSPlay).
  jsSettings(sourceMapsBase := baseDirectory.value / "..")

lazy val sharedJvm = shared.jvm
lazy val sharedJs = shared.js



// loads the Play project at sbt startup
onLoad in Global := (Command.process("project playServer", _: State)) compose (onLoad in Global).value
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.