spaced / scala-js-d3

d3 facade types for Scala.js
BSD 3-Clause "New" or "Revised" License
104 stars 28 forks source link

Usage of DatumFunction #17

Open littler00t opened 8 years ago

littler00t commented 8 years ago

Hello,

I am trying to "port" this Scatterplot example (http://bl.ocks.org/weiglemc/6185069) to scala-js-d3

Unfortunately, I am having some trouble understanding the proper use of DatumFunction. Please see my code, which I just added to your example project:

https://gist.github.com/littler00t/943b1cd79c7922229dff

See lines 121ff : I understand the return type of DatumFunction should be String and the "Datum" type is also String.

Nevertheless, I get compilation error:

[error] ... scala-js-d3-example-app/src/main/scala/example/ScalaJSExample.scala:121: type mismatch;
[error]  found   : (String, Int, Int) => String
[error]  required: legend.DatumFunction[org.singlespaced.d3js.d3.Primitive]
[error]     (which expands to)  scala.scalajs.js.Function3[String,Int,Int,scala.scalajs.js.|[scala.scalajs.js.|[Double,String],Boolean]]
[error]     val transformLegend: legend.DatumFunction[d3.Primitive] = { (d: String, x: Int, y: Int) => "translate(0," + x * 20 + ")" }
[error]                                                                                             ^
[error] ... scala-js-d3-example-app/src/main/scala/example/ScalaJSExample.scala:124: type mismatch;
[error]  found   : (String, Int, Int) => String
[error]  required: scala.scalajs.js.Function3[String,Int,Int,org.singlespaced.d3js.d3.Primitive]
[error]     (which expands to)  scala.scalajs.js.Function3[String,Int,Int,scala.scalajs.js.|[scala.scalajs.js.|[Double,String],Boolean]]
[error]     val transformLegend2: scala.scalajs.js.Function3[String, Int, Int, d3.Primitive] = { (d: String, x: Int, y: Int) => "translate(0," + x * 20 + ")" }
[error]                                                                                                                      ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed

Would be great if you could help. It's probably just a minor issue coming from my lack of understanding so any help is greatly appreciated :-) If I finish the scatterplot, maybe it can serve as an example on how to handle this kind of stuff.

Thanks

jtvoorde commented 8 years ago

I had the same problem when converting the force directed graph example. I solved it by casting the function result type to Primitive. Like this:

node.style("fill", (d: Node, a: Int, b: Int) => colorStr: Primitive)

littler00t commented 8 years ago

Thanks, that worked!

spaced commented 8 years ago

thats true, using all parameters uses the wrong implicit. But in your case, using only two parameter function works as expected:

    val transformLegend  =  (d: String, i: Int) => "translate(0, " + i * 20 + ")"
francoiscabrol commented 8 years ago

Hi, I have the same problem with this code:

    val selector = "#viz"
    val sampleSVG = d3.select(selector)
        .append("svg")
        .attr("width", 100)
        .attr("height", 100);

    sampleSVG.append("circle")
        .style("stroke", "gray")
        .style("fill", "white")
        .attr("r", 40)
        .attr("cx", 50)
        .attr("cy", 50)
        .on("mouseover",  () => {d3.select(sampleSVG.node()).style("fill", "blue")})
        .on("mouseout", () => {d3.select(sampleSVG.node()).style("fill", "white")})

I don't understand how to get it works. I have tried a lot of things and impossible to have the good implicit conversion...

jiangzhe commented 8 years ago

I guess you can import org.singlespaced.d3js.Ops._ which contains many implicit convertions. If no suitable one, you may need write you own.

francoiscabrol commented 8 years ago

Finally, it was not the implicit conversion but the returned values and the parameters. This worked:

    sampleSVG.append("circle")
      .style("stroke", "gray")
      .style("fill", "white")
      .attr("r", 40)
      .attr("cx", 50)
      .attr("cy", 50)
      .on("mouseover", (e: EventTarget) => { d3.select(circle.node()).style("fill", "blue") }:Unit)
      .on("mouseout", (e: EventTarget) => { d3.select(circle.node()).style("fill", "white") }: Unit)