0

I'm trying to write a facade for C3.js line chart.

The Javascript code I'm trying to generate is

var chart = c3.generate({
    data: {
        json: {
            "data1": [49.1, 20, 50, 40, 60, 50],
            "data2": [200.3, 130, 90, 240, 130, 220],
            "data3": [300.88, 200, 160, 400, 250, 250]
        }
    }
});

This is how I'm invoking the facade I've written

C3Chart.generate(scope.props.data)

The problem is that I'm not able to convert the apply method in C3MyChartDataset class to return a json object to emit this object

 json: {
        "data1": [49.1, 20, 50, 40, 60, 50],
        "data2": [200.3, 130, 90, 240, 130, 220],
        "data3": [300.88, 200, 160, 400, 250, 250]
    }

How do I convert a Map to a JSON object in Scala-js ?

@JSName("c3")
object C3Chart extends js.Object {
  def generate(data: MyChartData): js.Dynamic = js.native
}

trait C3MyChartDataset extends js.Object {
  def json: js.Object = js.native
}

object C3MyChartDataset {
  def apply(data: Map[String, Array[Double]]): C3MyChartDataset = {
    js.Dynamic.literal(
      json = data //I need to convert this into an object
    ).asInstanceOf[C3MyChartDataset]
  }
}

trait MyChartData extends js.Object {
  def data: js.Object = js.native
}

object MyChartData {
  def apply(datasets: C3MyChartDataset): MyChartData = {
    js.Dynamic.literal(
      data = datasets
    ).asInstanceOf[MyChartData]
  }
}

Update: I've tried converting it to Dictionary object by using toJSDictionary. (json = data.toJSDictionary). But this still does not generate the chart. The resulting Javascript object using toJSDictionary is

data: Object
    json: Object
        Data1: $TypeData.initArray.ArrayClass
           u: Array[6]
           0: 30.1
           1: 200.1
           2: 100.1
           3: 400.1
           4: 150.1
           5: 250.1
user794783
  • 3,619
  • 7
  • 36
  • 58
  • 1
    I assume you just need a JavaScript object, not JSON per se, right? (JSON is the serialized form, but it doesn't look like that's what you are looking for.) – Justin du Coeur Jul 27 '15 at 14:00
  • I'm sorry I am very new to Javascript. I'm just trying to generate the code snippet in Javascript from Scalajs that C3.js requires to display the charts. I just need to my Map to emit the json object/javascript object. – user794783 Jul 27 '15 at 14:03
  • 1
    Sounds like the library's documentation is confusing. JSON is the *stringified* format of a JavaScript object, not the object itself. But yeah -- as I answer below, try turning your map into a js.Dictionary, and assign that to the "json" parameter. It seems like it ought to be right... – Justin du Coeur Jul 27 '15 at 14:08

2 Answers2

6

The type of your json object is basically a dictionary whose values are arrays of numbers. Translated to a Scala.js type, that means

js.Dictionary[js.Array[Double]]

You can convert your data of type Map[String, Array[Double]] to that type with

data.mapValues(_.toJSArray).toJSDictionary
sjrd
  • 21,805
  • 2
  • 61
  • 91
  • That worked thanks heaps. Does this mean that every time I try to load the chart the values will be iterated and converted to js objects ? or does this conversion is only at initial compile when Scala is transpiled to Javascript ? – user794783 Jul 27 '15 at 14:39
  • 1
    It will be converted every time you call that `apply()` method, yes. If you don't want any conversion to happen, you have to use `js.Dictionary` and `js.Array` at call site in the first place. – sjrd Jul 27 '15 at 14:41
1

Assuming my question above is correct, you probably want js.Dictionary -- this is the usual Scala.js representation of a normal JavaScript object that you think of as name/value pairs. Note that it has a (String, A)* constructor that is pretty easy to convert from Map.

Justin du Coeur
  • 2,699
  • 1
  • 14
  • 19
  • I've tried that. Updated my answer with the results I got from using import scala.scalajs.js.JSConverters.toJSDictionary. May be it's the ArrayClass causing the issue :S – user794783 Jul 27 '15 at 14:10