Skip to content

Instantly share code, notes, and snippets.

@simerplaha
Last active May 16, 2018 13:40
Show Gist options
  • Save simerplaha/7483a4efe0599b239b31 to your computer and use it in GitHub Desktop.
Save simerplaha/7483a4efe0599b239b31 to your computer and use it in GitHub Desktop.
A simple Scala-js C3.js Charts facade ... Something I wrote quickly to integrate C3.js charts. Hopefully it will be good enough for anyone to get started with C3.js charts in Scala.js. I will try to make the parameters more type safe objects soon and implement the APIs properly.
import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.annotation.JSName
trait C3ChartObject extends js.Object {
def load(data: C3JSChartDataset): js.Dynamic = js.native
def unload() = js.native
}
@JSName("c3")
object C3Chart extends js.Object {
def generate(data: C3JSChartData): C3ChartObject = js.native
}
trait C3JSChartDataset extends js.Object {
}
object C3JSChartDataset {
def apply(`type`: js.UndefOr[String] = js.undefined,
types: Map[String, String] = Map.empty[String, String],
xs: Map[String, String] = Map.empty[String, String],
ys: Map[String, String] = Map.empty[String, String],
xAxisDataId: js.UndefOr[String] = js.undefined,
data: Map[String, js.Array[Any]],
colors: Map[String, String] = Map.empty[String, String],
axes: Map[String, String] = Map.empty[String, String],
groups: List[List[String]] = List.empty[List[String]]) = {
js.Dynamic.literal(
x = xAxisDataId,
xs = xs.toJSDictionary,
ys = ys.toJSDictionary,
columns = data.values.toJSArray,
groups = groups.map(_.toJSArray).toJSArray,
`type` = `type`,
types = types.toJSDictionary,
keys = js.Dynamic.literal(
value = data.keys.toJSArray
),
colors = colors.toJSDictionary,
axes = axes.toJSDictionary
).asInstanceOf[C3JSChartDataset]
}
}
trait C3JSChartData extends js.Object {
def bindto: String = js.native
def data: C3JSChartDataset = js.native
}
trait Region extends js.Object {
def start: Long = js.native
def end: Long = js.native
def `class`: js.UndefOr[String] = js.native
def style: js.UndefOr[String] = js.native
}
object Region {
def apply(start: Long,
end: Long,
`class`: js.UndefOr[String] = js.undefined,
style: js.UndefOr[String] = js.undefined) = js.Dynamic.literal(
start = start,
end = end,
`class` = `class`,
style = style
).asInstanceOf[Region]
}
object C3JSChartData {
def apply(bindTo: String = "chart",
`size.height`: js.UndefOr[Int] = js.undefined,
`size.width`: js.UndefOr[Int] = js.undefined,
`zoom.enabled`: js.UndefOr[Boolean] = js.undefined,
`zoom.rescale`: js.UndefOr[Boolean] = js.undefined,
`grid.y.show`: js.UndefOr[Boolean] = js.undefined,
xAxisType: js.UndefOr[String] = js.undefined,
xTickFormat: js.UndefOr[(Any) => String] = js.undefined,
yTickFormat: js.UndefOr[(Any) => String] = js.undefined,
`tooltip.format.title`: js.UndefOr[(Double) => String] = js.undefined,
`tooltip.format.value`: js.UndefOr[(Double, js.UndefOr[String], js.UndefOr[String]) => String] = js.undefined,
xAxisLabel: js.UndefOr[String] = js.undefined,
yAxisLabel: js.UndefOr[String] = js.undefined,
y2AxisLabel: js.UndefOr[String] = js.undefined,
fitX: js.UndefOr[Boolean] = js.undefined,
rotateX: js.UndefOr[Int] = js.undefined,
multilineX: js.UndefOr[Boolean] = js.undefined,
cullingMaxX: js.UndefOr[Int] = js.undefined,
heightX: js.UndefOr[Int] = js.undefined,
showAdditionalYAxis: js.UndefOr[Boolean] = js.undefined,
rotated: js.UndefOr[Boolean] = js.undefined,
regions: js.UndefOr[js.Array[Region]] = js.undefined,
showPoint: Boolean = true,
data: C3JSChartDataset): C3JSChartData = {
js.Dynamic.literal(
bindto = s"#$bindTo",
data = data,
regions = regions,
grid = js.Dynamic.literal(
y = js.Dynamic.literal(
show = `grid.y.show`
)
),
size = js.Dynamic.literal(
height = `size.height`,
width = `size.width`
),
zoom = js.Dynamic.literal(
enabled = `zoom.enabled`,
rescale = `zoom.rescale`
),
point = js.Dynamic.literal(
show = showPoint
),
tooltip = js.Dynamic.literal(
format = js.Dynamic.literal(
title = `tooltip.format.title`,
value = `tooltip.format.value`
)
),
axis = js.Dynamic.literal(
x = js.Dynamic.literal(
`type` = xAxisType,
label = xAxisLabel,
height = heightX,
tick = js.Dynamic.literal(
format = xTickFormat,
fit = fitX,
rotate = rotateX,
multiline = multilineX,
culling = js.Dynamic.literal(
max = cullingMaxX
)
)
),
y = js.Dynamic.literal(
label = yAxisLabel,
tick = js.Dynamic.literal(
format = yTickFormat
)
),
y2 = js.Dynamic.literal(
label = y2AxisLabel,
show = showAdditionalYAxis
),
rotated = rotated
)
).asInstanceOf[C3JSChartData]
}
}
@Rodrigo-Martinez-Jacobson

I'm having problems with the input data, it doesn't like the array type being Any :

data: Map[String, js.Array[Any]]

But it works if I change it to Double or Int

@Rodrigo-Martinez-Jacobson

Trying with a List[Any] seems to compile, but the chart doesn't show and I get the following error in the javascript console:

Uncaught TypeError: (0 , $g.C3JSChartDataset) is not a function

The list i'm using is this one:
val exampleList: List[Any] = List("angelitos",30,50,60,80)

@prassee
Copy link

prassee commented Mar 2, 2018

data = C3JSChartDataset(
        `type` = "line",
        x = "date",
        data = myData
      )

in C3JSChartDataSet i don't see the variable x using this code throws a error please verify

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment