0

I'm trying to create a world map with topojson and d3-geo using scalajs based on the following example: How-to-create-pure-react-SVG-maps-with-topojson-and-d3-geo

My biggest issue so far is what I don't understand how I can implement geoEqualEarth() and geoPath() functions from d3-geo using scala since both of them have a number of methods, for example const projection = geoEqualEarth().scale(160).translate([ 800 / 2, 450 / 2 ]). This piece of code suppose to create a projection (which is assumed to be an array of numeric values), and that projection is later used in geoPath().projection(projection)(d) to create a proper input string for the <d> tag. I'm really confused about how such kind of logic can be implemented in scala and I'm not sure if I can use pure JS in this case.

1 Answer 1

1

how I can implement geoEqualEarth() and geoPath() functions from d3-geo

I assume that what you mean by that is using those functions, which are defined in the JavaScript library d3-geo, from Scala.js.

In general, to use JavaScript libraries from Scala.js, you either define facade types for the library, or reuse one that is already existing, perhaps through ScalablyTyped. How the facades are declared depends mostly on what the API looks like, and how it's supposed to be used.

Just trying to make your example snippets valid, I would aim for

@js.native
trait Projection extends js.Object {
  def scale(factor: Double): this.type
  def translate(v: js.Tuple2[Double, Double]): this.type
}

@js.native
trait Path extends js.Object {
  def projection(p: Projection): Path
  def apply(obj: js.Any): Something = js.native
}

// import { geoEqualEarth, geoPath } from "d3-geo"
object D3GeoFunctions {
  @js.native
  @JSImport("d3-geo", "geoEqualEarth")
  def geoEqualEarth(): Projection = js.native

  @js.native
  @JSImport("d3-geo", "geoPath")
  def geoPath(): Path = js.native
}

although a lot of this is guesswork based on your snippet and skimming the d3-geo readme.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the tip, it looks like more or less what I'm trying to do but I'm struggling to properly define facades for these two functions. Based on your example I've tried to define a facade for the Projection like: @js.native trait Projection extends js.Function1[js.Tuple2[Double,Double],js.Tuple2[Double,Double]] { def apply(lonLat:js.Tuple2[Double,Double]): js.Tuple2[Double, Double] = js.native def scale(factor: Double): this.type def translate(v: js.Tuple2[Int, Int]): this.type }, but got Uncaught TypeError: $i_d3$002dgeo is undefined
Thanks again, I modified this example a little bit and it worked for me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.