Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions client/src/main/scala/spatutorial/client/SPAMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ object SPAMain extends js.JSApp {

case object TodoLoc extends Loc

case object LocationsLoc extends Loc

// configure the router
val routerConfig = RouterConfigDsl[Loc].buildConfig { dsl =>
import dsl._

// wrap/connect components to the circuit
(staticRoute(root, DashboardLoc) ~> renderR(ctl => SPACircuit.wrap(_.motd)(proxy => Dashboard(ctl, proxy)))
(emptyRule
| staticRoute(root, DashboardLoc) ~> renderR(ctl => SPACircuit.wrap(_.motd)(proxy => Dashboard(ctl, proxy)))
| staticRoute("#todo", TodoLoc) ~> renderR(ctl => SPACircuit.connect(_.todos)(Todo(_)))
| staticRoute("#locations", LocationsLoc) ~> renderR(ctl => Locations())
).notFound(redirectToPage(DashboardLoc)(Redirect.Replace))
}.renderWith(layout)

Expand All @@ -48,7 +52,7 @@ object SPAMain extends js.JSApp {
)
),
// currently active module is shown in this container
<.div(^.className := "container", r.render())
<.div(^.className := "container-fluid", r.render())
)
}

Expand Down
89 changes: 11 additions & 78 deletions client/src/main/scala/spatutorial/client/components/Chart.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,80 +3,7 @@ package spatutorial.client.components
import japgolly.scalajs.react.vdom.prefix_<^._
import japgolly.scalajs.react.{Callback, ReactComponentB}
import org.scalajs.dom.raw.HTMLCanvasElement

import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.annotation.JSName

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

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

@js.native
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]
}
}

@js.native
trait ChartOptions extends js.Object {
def responsive: Boolean = js.native
}

object ChartOptions {
def apply(responsive: Boolean = true): ChartOptions = {
js.Dynamic.literal(
responsive = responsive
).asInstanceOf[ChartOptions]
}
}

@js.native
trait ChartConfiguration extends js.Object {
def `type`: String = js.native
def data: ChartData = js.native
def options: ChartOptions = js.native
}

object ChartConfiguration {
def apply(`type`: String, data: ChartData, options: ChartOptions = ChartOptions(true)): ChartConfiguration = {
js.Dynamic.literal(
`type` = `type`,
data = data,
options = options
).asInstanceOf[ChartConfiguration]
}
}

// define a class to access the Chart.js component
@js.native
@JSName("Chart")
class JSChart(ctx: js.Dynamic, config: ChartConfiguration) extends js.Object
import spatutorial.client.components.chart.{Chart, ChartConfiguration, ChartData}

object Chart {

Expand All @@ -87,20 +14,26 @@ object Chart {

case object BarChart extends ChartStyle

case class ChartProps(name: String, style: ChartStyle, data: ChartData, width: Int = 400, height: Int = 200)
case class ChartProps(name: String,
style: ChartStyle,
data: ChartData,
width: Int = 500,
height: Int = 300)

val Chart = ReactComponentB[ChartProps]("Chart")
.render_P(p =>
<.canvas(^.width := s"${p.width}px", ^.height := s"${p.height}px")
<.canvas(
^.width := s"${p.width}px",
^.height := s"${p.height}px")
)
.domType[HTMLCanvasElement]
.componentDidMount(scope => Callback {
// access context of the canvas
val ctx = scope.getDOMNode().getContext("2d")
// create the actual chart using the 3rd party component
scope.props.style match {
case LineChart => new JSChart(ctx, ChartConfiguration("line", scope.props.data))
case BarChart => new JSChart(ctx, ChartConfiguration("bar", scope.props.data))
case LineChart => new Chart(ctx, ChartConfiguration("line", scope.props.data))
case BarChart => new Chart(ctx, ChartConfiguration("bar", scope.props.data))
case _ => throw new IllegalArgumentException
}
}).build
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
package spatutorial.client.components

import scalacss.Defaults._
import scalacss.Dsl

object GlobalStyles extends StyleSheet.Inline {
import dsl._

import Dsl._

val navbarHeight = 50

style(unsafeRoot("body")(
paddingTop(70.px))
)

// full-screen map
style(unsafeRoot("#map")(
marginTop(-20.px),
marginLeft(-15.px),
marginRight(-15.px)
))

val bootstrapStyles = new BootstrapStyles

val chart = style(width(500.px), height(300.px))

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package spatutorial.client.components

import japgolly.scalajs.react.vdom.prefix_<^._
import japgolly.scalajs.react.{Callback, ReactComponentB}
import org.scalajs.dom
import org.scalajs.dom.raw.HTMLDivElement
import spatutorial.client.components.map._

object LeafletMap {

case class MapProps(name: String)

private def demoTileLayer = Leaflet.tileLayer("https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw", TileLayerOptions(
maxZoom = 18,
attribution =
"""Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors,
|<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>,
|Imagery © <a href="http://mapbox.com">Mapbox</a>
""".stripMargin,
id = "mapbox.streets"
))

val LeafletMap = ReactComponentB[MapProps]("Map")
.render_P(p =>
<.div(^.id := "map", ^.height := mapHeight)
)
.domType[HTMLDivElement]
.componentDidMount(scope => Callback {
val id = scope.getDOMNode().getAttribute("id")
val map = Leaflet.map(id)
DefaultIcon.imagePath = "assets/lib/leaflet/images"
map.setView(new LatLng(51.505, -0.09), 13)
val marker = Leaflet.marker(new LatLng(51.505, -0.09), MarkerOptions(new DefaultIcon())).addTo(map)
marker.bindPopup("Hi, I am a Popup!").openPopup()
demoTileLayer.addTo(map)
})
.build

private def mapHeight: String = s"${dom.window.innerHeight - GlobalStyles.navbarHeight}px"

def apply(props: MapProps) = LeafletMap(props)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package spatutorial.client.components.chart

import scala.scalajs.js
import scala.scalajs.js.annotation.JSName

@js.native
@JSName("Chart")
class Chart(ctx: js.Dynamic, config: ChartConfiguration) extends js.Object
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package spatutorial.client.components.chart

import scala.scalajs.js

@js.native
trait ChartConfiguration extends js.Object {
def `type`: String = js.native

def data: ChartData = js.native

def options: ChartOptions = js.native
}

object ChartConfiguration {
def apply(`type`: String,
data: ChartData,
options: ChartOptions = ChartOptions(
responsive = true,
maintainAspectRatio = false
)): ChartConfiguration = {
js.Dynamic.literal(
`type` = `type`,
data = data,
options = options
).asInstanceOf[ChartConfiguration]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package spatutorial.client.components.chart

import scala.scalajs.js
import scala.scalajs.js.JSConverters._


@js.native
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]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package spatutorial.client.components.chart

import scala.scalajs.js
import scala.scalajs.js.JSConverters._

@js.native
trait ChartDataset extends js.Object {
def label: String = js.native

def data: js.Array[Double] = js.native

def fillColor: String = js.native

def strokeColor: String = js.native
}

object ChartDataset {
def apply(data: Seq[Double],
label: String,
backgroundColor: String = "#8080FF",
borderColor: String = "#404080",
hoverBackgroundColor: String = "#8080FF"): ChartDataset = {
js.Dynamic.literal(
label = label,
data = data.toJSArray,
backgroundColor = backgroundColor,
borderColor = borderColor,
hoverBackgroundColor = hoverBackgroundColor
).asInstanceOf[ChartDataset]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package spatutorial.client.components.chart

import scala.scalajs.js

@js.native
trait ChartOptions extends js.Object {
def responsive: Boolean = js.native
}

object ChartOptions {
def apply(responsive: Boolean = true, maintainAspectRatio: Boolean = false): ChartOptions = {
js.Dynamic.literal(
responsive = responsive,
maintainAspectRatio = maintainAspectRatio
).asInstanceOf[ChartOptions]
}
}
51 changes: 51 additions & 0 deletions client/src/main/scala/spatutorial/client/components/map/Icon.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package spatutorial.client.components.map

import scala.scalajs.js
import scala.scalajs.js.annotation.JSName

@js.native
trait IconOptions extends js.Object

object IconOptions {
def apply(iconUrl: String,
iconRetinaUrl: String,
iconSize: Point,
iconAnchor: Point,
popupAnchor: Point,
shadowUrl: String,
shadowRetinaUrl: String,
shadowSize: Point,
shadowAnchor: Point,
className: String = ""): IconOptions = {
js.Dynamic.literal(
iconUrl = iconUrl,
iconRetinaUrl = iconRetinaUrl,
iconSize = iconSize,
iconAnchor = iconAnchor,
popupAnchor = popupAnchor,
shadowUrl = shadowUrl,
shadowRetinaUrl = shadowRetinaUrl,
shadowSize = shadowSize,
shadowAnchor = shadowAnchor,
className = className
).asInstanceOf[IconOptions]
}
}

@js.native
trait Icon extends js.Object {
}

@js.native
@JSName("L.Icon")
object Icon extends js.Object

@js.native
@JSName("L.Icon.Default")
class DefaultIcon extends Icon

@js.native
@JSName("L.Icon.Default")
object DefaultIcon extends js.Object {
var imagePath: String = js.native
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package spatutorial.client.components.map

import scala.scalajs.js
import scala.scalajs.js.annotation.JSName


@js.native
@JSName("L.LatLng")
class LatLng(lat: Double, lng: Double) extends js.Object
Loading