Last active
May 16, 2018 13:40
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] | |
} | |
} |
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
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)
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
I don't really have a tutorial. But the C3js documentation is very well written. After you create your
C3JSChartData
object all you have to do is invoke thegenerate
method onC3Chart
object (c3
in Javascript) passing it your data.C3Chart.generate(yourChartData)
And the above will render/generate the Chart.
Javascript equivalent would be
you can see one of the C3.js example here to see how they are creating their input objects in JSON. To get you started below is a small sample (untested!). I'm also using scalajs-momentjs here to format this timeseries chart's x axis to
D MMM YYYY, HH:mm
.