├── .git-blame-ignore-revs ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .jitpack.yml ├── .mergify.yml ├── .scalafmt.conf ├── LICENSE ├── build.sbt ├── project ├── build.properties └── plugins.sbt ├── readme.md ├── src └── main │ └── scala │ ├── Array.scala │ ├── Axis.scala │ ├── Color.scala │ ├── D3.scala │ ├── Drag.scala │ ├── Force.scala │ ├── Hierarchy.scala │ ├── Polygon.scala │ ├── Quadtree.scala │ ├── Scale.scala │ ├── Selection.scala │ ├── Shape.scala │ ├── Time.scala │ ├── Transition.scala │ └── Zoom.scala └── yarn.lock /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Scala Steward: Reformat with scalafmt 3.6.0 2 | 6bb704e2f4cdec77ce43ee9cec34b6a98e8edfbd 3 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | push: 4 | branches: [master] 5 | tags: [ v* ] 6 | pull_request: 7 | workflow_dispatch: 8 | jobs: 9 | build: 10 | strategy: 11 | matrix: 12 | scalaVersion: ["2.12.20", "2.13.16", "3.6.4"] 13 | runs-on: ubuntu-20.04 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | ref: ${{ github.event.pull_request.head.sha }} 19 | - uses: coursier/cache-action@v6 20 | - uses: olafurpg/setup-scala@v12 21 | 22 | - name: Test 23 | run: sbt "++${{matrix.scalaVersion}} test" 24 | 25 | # - name: Debug over SSH (tmate) 26 | # # if: ${{ failure() }} 27 | # uses: mxschmitt/action-tmate@v3 28 | # with: 29 | # limit-access-to-actor: true 30 | 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | *.gpg 3 | sonatype.sbt 4 | project/metals.sbt 5 | .bsp 6 | .idea 7 | 8 | -------------------------------------------------------------------------------- /.jitpack.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - SBT_OPTS="-Xms1G -Xmx8G -Xss16M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC" sbt +publishM2 3 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | queue_rules: 2 | - name: default 3 | conditions: 4 | # Conditions to get out of the queue (= merged) 5 | - check-success~=build \(2\.12\.\d+\) 6 | - check-success~=build \(2\.13\.\d+\) 7 | - check-success~=build \(3\.\d+\.\d+\) 8 | 9 | pull_request_rules: 10 | - name: Label Scala Steward PRs 11 | conditions: 12 | - author=scala-steward 13 | actions: 14 | label: 15 | add: [dependencies, scala] 16 | 17 | - name: Merge dependency-update PRs 18 | conditions: 19 | - base=master 20 | - label=dependencies 21 | - check-success~=build \(2\.12\.\d+\) 22 | - check-success~=build \(2\.13\.\d+\) 23 | - check-success~=build \(3\.\d+\.\d+\) 24 | actions: 25 | queue: 26 | name: default 27 | method: squash 28 | 29 | 30 | - name: Merge PRs (rebase) which are ready to merge 31 | conditions: 32 | - label=ready-to-merge-rebase 33 | - base=master 34 | - check-success~=build \(2\.12\.\d+\) 35 | - check-success~=build \(2\.13\.\d+\) 36 | - check-success~=build \(3\.\d+\.\d+\) 37 | - "#review-requested=0" 38 | - "#changes-requested-reviews-by=0" 39 | actions: 40 | queue: 41 | name: default 42 | method: rebase 43 | 44 | 45 | - name: Merge PRs (squash) which are ready to merge 46 | conditions: 47 | - label=ready-to-merge-squash 48 | - base=master 49 | - check-success~=build \(2\.12\.\d+\) 50 | - check-success~=build \(2\.13\.\d+\) 51 | - check-success~=build \(3\.\d+\.\d+\) 52 | - "#review-requested=0" 53 | - "#changes-requested-reviews-by=0" 54 | actions: 55 | queue: 56 | name: default 57 | method: squash 58 | -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | version = "3.9.4" 2 | runner.dialect = scala3 3 | maxColumn = 120 4 | trailingCommas = always 5 | align.preset = most 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | name := "scala-js-d3v4" 2 | version := "master-SNAPSHOT" 3 | organization := "com.github.fdietze.scala-js-d3v4" 4 | 5 | crossScalaVersions := Seq("2.12.20", "2.13.16", "3.6.4") 6 | scalaVersion := crossScalaVersions.value.last 7 | 8 | val isScala3 = Def.setting(CrossVersion.partialVersion(scalaVersion.value).exists(_._1 == 3)) 9 | 10 | scalacOptions --= Seq("-Xfatal-warnings") // overwrite sbt-tpolecat setting 11 | scalacOptions ++= (if (isScala3.value) Seq("-scalajs") else Nil) // needed for Scala3 + ScalaJS 12 | 13 | enablePlugins(ScalaJSPlugin, ScalaJSBundlerPlugin) 14 | 15 | libraryDependencies ++= Seq( 16 | "org.scala-js" %%% "scalajs-dom" % "2.8.0", 17 | ) 18 | Compile / npmDependencies ++= Seq( 19 | "d3" -> "5.9.2", // https://github.com/d3/d3/releases 20 | ) 21 | 22 | useYarn := true 23 | 24 | /* pgpSecretRing in Global := file("secring.gpg") */ 25 | /* pgpPublicRing in Global := file("pubring.gpg") */ 26 | /* pgpPassphrase in Global := Some("".toCharArray) */ 27 | 28 | /* organization in Global := "com.github.fdietze" */ 29 | 30 | /* pomExtra := { */ 31 | /* https://github.com/fdietze/scala-js-d3v4 */ 32 | /* */ 33 | /* */ 34 | /* MIT */ 35 | /* http://opensource.org/licenses/MIT */ 36 | /* */ 37 | /* */ 38 | /* */ 39 | /* https://github.com/fdietze/scala-js-d3v4 */ 40 | /* scm:git:git@github.com:fdietze/scala-js-d3v4.git */ 41 | /* */ 42 | /* */ 43 | /* */ 44 | /* fdietze */ 45 | /* Felix Dietze */ 46 | /* https://github.com/fdietze */ 47 | /* */ 48 | /* */ 49 | /* } */ 50 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.10.11 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.18.2") 2 | addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.21.1") 3 | addSbtPlugin("com.thoughtworks.sbt-scala-js-map" % "sbt-scala-js-map" % "4.1.1") 4 | 5 | addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.2") 6 | addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") 7 | 8 | addSbtPlugin("org.typelevel" % "sbt-tpolecat" % "0.5.2") 9 | 10 | addSbtPlugin("com.github.sbt" % "sbt-git" % "2.1.0") 11 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [![](https://jitpack.io/v/fdietze/scala-js-d3v4.svg)](https://jitpack.io/#fdietze/scala-js-d3v4) 2 | 3 | # ScalaJS facade types for D3 version 5 4 | * Heavily inspired by [spaced/scala-js-d3](https://github.com/spaced/scala-js-d3) 5 | * D3 modules are imported automatically by bundler when needed. 6 | 7 | ## Usage 8 | Supported are ScalaJS` 1.0` with Scala `2.12` and `2.13`. 9 | 10 | 11 | * Set up [Scalajs-Bundler](https://scalacenter.github.io/scalajs-bundler/) for your project. 12 | * In your `build.sbt`: 13 | ```scala 14 | resolvers += "jitpack" at "https://jitpack.io" 15 | libraryDependencies += "com.github.fdietze.scala-js-d3v4" %%% "scala-js-d3v4" % "809f086" 16 | ``` 17 | 18 | Don't forget to update the commit hash. You can also use the hashes of branches and PRs. 19 | 20 | * Use d3 like you know it from JavaScript (http://devdocs.io/d3~4): 21 | 22 | ```scala 23 | import d3v4._ 24 | 25 | d3.___ 26 | ``` 27 | 28 | * Contribute missing facades as pull requests. Most of the time this can be done in a few lines of code. You get a good overview of what exists and what is missing when looking at [src/main/scala](https://github.com/fdietze/scala-js-d3v4/tree/master/src/main/scala). Each File corresponds to a module in d3: https://devdocs.io/d3~4. To add a new module, simply create a new file and implement the facades you need. Finally add an implicit to your module in [D3.scala](https://github.com/fdietze/scala-js-d3v4/blob/master/src/main/scala/D3.scala#L38). 29 | * Don't hesitate to open new Issues. 30 | 31 | ## Facade writing guidelines 32 | * Ref types involving null don't need a union type with Null. Provide wrapper methods mapping to Option. 33 | * Prefer overloading in most cases. But use union types to avoid combinatorial explosion. 34 | -------------------------------------------------------------------------------- /src/main/scala/Array.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | import org.scalajs.dom 7 | import d3._ 8 | 9 | // https://github.com/d3/d3-array 10 | @JSImport("d3-array", JSImport.Namespace) 11 | @js.native 12 | object d3array extends js.Object { 13 | def extent[T](array: js.Array[T]): js.Array[T] = js.native 14 | def extent[T, R](array: js.Array[T], accessor: js.Function1[T, R]): js.Array[R] = js.native 15 | 16 | def ticks[T](start: T, stop: T, count: Int): js.Array[T] = js.native 17 | def tickIncrement[T](start: T, stop: T, count: Int): js.Array[T] = js.native 18 | def tickStep[T](start: T, stop: T, count: Int): js.Array[T] = js.native 19 | 20 | def range[T](start: T, stop: T, count: Int): js.Array[T] = js.native 21 | def range[T](stop: T, step: T): js.Array[T] = js.native 22 | def range[T](stop: T): js.Array[T] = js.native 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/Axis.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | import d3._ 7 | 8 | // https://github.com/d3/d3-axis 9 | 10 | @JSImport("d3-axis", JSImport.Namespace) 11 | @js.native 12 | object d3axis extends js.Object { 13 | def axisTop(scale: Scale): Axis = js.native 14 | def axisRight(scale: Scale): Axis = js.native 15 | def axisBottom(scale: Scale): Axis = js.native 16 | def axisLeft(scale: Scale): Axis = js.native 17 | 18 | @js.native 19 | trait Axis extends js.Function { 20 | def apply(context: Selection[_]): Unit = js.native 21 | def scale(): Scale = js.native 22 | def scale(scale: Scale): Axis = js.native 23 | def ticks(count: Int): Axis = js.native 24 | def ticks(count: Int, specifier: String): Axis = js.native 25 | def ticks(interval: Interval): Axis = js.native 26 | def ticks(interval: Interval, specifier: String): Axis = js.native 27 | def ticks(arguments: js.Object*): Axis = js.native 28 | def tickArguments(): js.Array[js.Any] = js.native 29 | def tickArguments[T](arguments: js.Array[T]): Axis = js.native 30 | def tickValues(): js.Array[js.Any] = js.native 31 | def tickValues[T](values: js.Array[T]): Axis = js.native 32 | def tickFormat(): js.Array[js.Any] = js.native 33 | def tickFormat(format: js.Object): Axis = js.native 34 | def tickSize(): Int = js.native 35 | def tickSize(size: Int): Axis = js.native 36 | def tickSizeInner(): Int = js.native 37 | def tickSizeInner(size: Int): Axis = js.native 38 | def tickSizeOuter(): Int = js.native 39 | def tickSizeOuter(size: Int): Axis = js.native 40 | def tickPadding(): Int = js.native 41 | def tickPadding(size: Int): Axis = js.native 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/scala/Color.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | 7 | // https://github.com/d3/d3-color 8 | @JSImport("d3-color", JSImport.Namespace) 9 | @js.native 10 | object d3color extends js.Object { 11 | def lab(l: Double, a: Double, b: Double): Lab = js.native 12 | def lab(l: Double, a: Double, b: Double, opacity: Double): Lab = js.native 13 | def lab(specifier: String): Lab = js.native 14 | def lab(color: Color): Lab = js.native 15 | 16 | def hcl(h: Double, c: Double, l: Double): Hcl = js.native 17 | def hcl(h: Double, c: Double, l: Double, opacity: Double): Hcl = js.native 18 | def hcl(specifier: String): Hcl = js.native 19 | def hcl(color: Color): Hcl = js.native 20 | 21 | def rgb(r: Int, g: Int, b: Int): Rgb = js.native 22 | def rgb(r: Int, g: Int, b: Int, opacity: Int): Rgb = js.native 23 | def rgb(specifier: String): Rgb = js.native 24 | def rgb(color: Color): Rgb = js.native 25 | 26 | @js.native 27 | trait Rgb extends Color { 28 | def r: Int = js.native 29 | def g: Int = js.native 30 | def b: Int = js.native 31 | def a: Int = js.native 32 | } 33 | 34 | @js.native 35 | trait Lab extends Color { 36 | def l: Double = js.native 37 | def a: Double = js.native 38 | def b: Double = js.native 39 | } 40 | 41 | @js.native 42 | trait Hcl extends Color { 43 | def h: Double = js.native 44 | def c: Double = js.native 45 | def l: Double = js.native 46 | } 47 | 48 | @js.native 49 | trait Color extends js.Object { 50 | var opacity: Double = js.native 51 | override def toString(): String = js.native 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/scala/D3.scala: -------------------------------------------------------------------------------- 1 | import scalajs.js.`|` 2 | import scalajs.js 3 | import scala.scalajs.js.annotation._ 4 | import org.scalajs.dom 5 | 6 | package d3v4 { 7 | object d3 { 8 | @inline implicit def d3toD3Array(d3t: d3.type): d3array.type = d3array 9 | @inline implicit def d3toD3Axis(d3t: d3.type): d3axis.type = d3axis 10 | @inline implicit def d3toD3Color(d3t: d3.type): d3color.type = d3color 11 | @inline implicit def d3toD3Drag(d3t: d3.type): d3drag.type = d3drag 12 | @inline implicit def d3toD3Force(d3t: d3.type): d3force.type = d3force 13 | @inline implicit def d3toD3Polygon(d3t: d3.type): d3polygon.type = d3polygon 14 | @inline implicit def d3toD3Scale(d3t: d3.type): d3scale.type = d3scale 15 | @inline implicit def d3toD3Selection(d3t: d3.type): d3selection.type = d3selection 16 | @inline implicit def d3toD3Shape(d3t: d3.type): d3shape.type = d3shape 17 | @inline implicit def d3toD3Time(d3t: d3.type): d3time.type = d3time 18 | @inline implicit def d3toD3Quadtree(d3t: d3.type): d3quadtree.type = d3quadtree 19 | @inline implicit def d3toD3Zoom(d3t: d3.type): d3zoom.type = d3zoom 20 | @inline implicit def d3toD3Transition(d3t: d3.type): d3transition.type = d3transition 21 | @inline implicit def d3toD3Hierarchy(d3t: d3.type): d3hierarchy.type = d3hierarchy 22 | 23 | @js.native 24 | trait BaseEvent extends js.Object { 25 | var `type`: String = js.native 26 | var sourceEvent: dom.Event = js.native 27 | } 28 | 29 | type DragEvent = d3drag.DragEvent 30 | type ZoomEvent = d3zoom.ZoomEvent 31 | type ZoomBehavior[Datum] = d3zoom.ZoomBehavior[Datum] 32 | type Transform = d3zoom.Transform 33 | type Selection[Datum] = d3selection.Selection[Datum] 34 | type Interval = d3time.Interval 35 | type Scale = d3scale.Scale 36 | type ContinuousScale[S <: d3scale.ContinuousScale[S]] = d3scale.ContinuousScale[S] 37 | type TimeScale = d3scale.TimeScale 38 | type Force[N <: SimulationNode] = d3force.Force[N] 39 | type Simulation[N <: SimulationNode] = d3force.Simulation[N] 40 | type Quadtree[Datum] = d3quadtree.Quadtree[Datum] 41 | type QuadtreeNode[Datum] = d3quadtree.QuadtreeNode[Datum] 42 | type Transition[Datum] = d3transition.Transition[Datum] 43 | type Hierarchy[Datum] = d3hierarchy.Hierarchy[Datum] 44 | } 45 | } 46 | 47 | package object d3v4 { 48 | import d3._ 49 | // type Primitive = Double | String | Boolean 50 | // 51 | // type DatumThisFunction3[Return] = js.ThisFunction3[CurrentDom, Datum, Index, Group, Return] 52 | // type DatumThisFunction2[Return] = js.ThisFunction2[CurrentDom, Datum, Index, Return] 53 | // type DatumThisFunction1[Return] = js.ThisFunction1[CurrentDom, Datum, Return] 54 | // type DatumThisFunction0[Return] = js.ThisFunction0[CurrentDom, Return] 55 | 56 | type CurrentDom = dom.EventTarget 57 | type Index = Int 58 | type Group = js.UndefOr[Int] 59 | 60 | type ValueFunction0[Return] = js.Function0[Return] 61 | type ValueFunction1[Datum, Return] = js.Function1[Datum, Return] 62 | type ValueFunction2[Datum, Return] = js.Function2[Datum, Index, Return] 63 | type ValueFunction3[Datum, Return] = js.Function3[Datum, Index, Group, Return] 64 | 65 | type ValueThisFunction0[C <: CurrentDom, Return] = js.ThisFunction0[C, Return] 66 | type ValueThisFunction1[C <: CurrentDom, Datum, Return] = js.ThisFunction1[C, Datum, Return] 67 | type ValueThisFunction2[C <: CurrentDom, Datum, Return] = js.ThisFunction2[C, Datum, Index, Return] 68 | type ValueThisFunction3[C <: CurrentDom, Datum, Return] = js.ThisFunction3[C, Datum, Index, Group, Return] 69 | 70 | type ListenerFunction0 = ValueFunction0[Unit] 71 | type ListenerFunction1[Datum] = ValueFunction1[Datum, Unit] 72 | type ListenerFunction2[Datum] = ValueFunction2[Datum, Unit] 73 | type ListenerFunction3[Datum] = ValueFunction3[Datum, Unit] 74 | 75 | type ListenerThisFunction0[C <: CurrentDom] = ValueThisFunction0[C, Unit] 76 | type ListenerThisFunction1[C <: CurrentDom, Datum] = ValueThisFunction1[C, Datum, Unit] 77 | type ListenerThisFunction2[C <: CurrentDom, Datum] = ValueThisFunction2[C, Datum, Unit] 78 | type ListenerThisFunction3[C <: CurrentDom, Datum] = ValueThisFunction3[C, Datum, Unit] 79 | 80 | implicit class SelectionExtensions[Datum](val s: Selection[Datum]) extends AnyVal { 81 | def nodeAs[T <: dom.EventTarget] = s.node().asInstanceOf[T] 82 | } 83 | 84 | implicit class SimulationExtensions[N <: SimulationNode](val s: Simulation[N]) extends AnyVal { 85 | def forceAs[F <: Force[N]](name: String) = s.force(name).asInstanceOf[F] 86 | } 87 | 88 | implicit def baseEventToZoomEvent(e: BaseEvent): ZoomEvent = e.asInstanceOf[ZoomEvent] 89 | implicit def baseEventToDragEvent(e: BaseEvent): DragEvent = e.asInstanceOf[DragEvent] 90 | } 91 | -------------------------------------------------------------------------------- /src/main/scala/Drag.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | import org.scalajs.dom 7 | import d3._ 8 | 9 | // https://github.com/d3/d3-drag 10 | @JSImport("d3-drag", JSImport.Namespace) 11 | @js.native 12 | object d3drag extends js.Object { 13 | def drag[Datum](): DragBehavior[Datum] = js.native 14 | 15 | @js.native 16 | trait DragEvent extends BaseEvent { 17 | var x: Double = js.native 18 | var y: Double = js.native 19 | var dx: Double = js.native 20 | var dy: Double = js.native 21 | } 22 | 23 | @js.native 24 | trait DragBehavior[Datum] extends js.Function1[Selection[Datum], Unit] { 25 | def on(typenames: String, listener: ListenerFunction0): DragBehavior[Datum] = js.native 26 | def on(typenames: String, listener: ListenerFunction1[Datum]): DragBehavior[Datum] = js.native 27 | def on(typenames: String, listener: ListenerFunction2[Datum]): DragBehavior[Datum] = js.native 28 | def on[E <: CurrentDom](typenames: String, listener: ListenerThisFunction2[E, Datum]): DragBehavior[Datum] = 29 | js.native 30 | 31 | type DragSubject = js.Object // {def x:Double; def y:Double} 32 | def subject(subject: ValueFunction2[Datum, DragSubject]): DragBehavior[Datum] = js.native 33 | 34 | def subject[E <: CurrentDom](subject: ValueThisFunction0[E, DragSubject]): DragBehavior[Datum] = js.native 35 | def subject[E <: CurrentDom](subject: ValueThisFunction1[E, Datum, DragSubject]): DragBehavior[Datum] = js.native 36 | def subject[E <: CurrentDom](subject: ValueThisFunction2[E, Datum, DragSubject]): DragBehavior[Datum] = js.native 37 | 38 | def clickDistance(distance: Double): DragBehavior[Datum] = js.native 39 | def clickDistance(): Double = js.native 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/scala/Force.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | 7 | // https://github.com/d3/d3-force 8 | 9 | @JSImport("d3-force", JSImport.Namespace) 10 | @js.native 11 | object d3force extends js.Object { 12 | def forceSimulation[N <: SimulationNode](nodes: js.Array[N] = js.Array[N]()): Simulation[N] = js.native 13 | def forceCenter[N <: SimulationNode](x: Double = 0, y: Double = 0): Centering[N] = js.native 14 | def forceX[N <: SimulationNode](x: Double = 0): PositioningX[N] = js.native 15 | def forceY[N <: SimulationNode](y: Double = 0): PositioningY[N] = js.native 16 | def forceManyBody[N <: SimulationNode](): ManyBody[N] = js.native 17 | def forceCollide[N <: SimulationNode](radius: Double = 1): Collision[N] = js.native 18 | def forceLink[N <: SimulationNode, L <: SimulationLink[_ <: N, _ <: N]]( 19 | links: js.Array[L] = js.Array[L](), 20 | ): Link[N, L] = js.native 21 | 22 | @js.native 23 | trait Simulation[N <: SimulationNode] extends js.Object { 24 | def restart(): this.type = js.native 25 | def stop(): this.type = js.native 26 | def tick(): this.type = js.native 27 | 28 | def nodes(nodes: js.Array[N]): this.type = js.native 29 | def nodes(): js.Array[N] = js.native 30 | 31 | def alpha(alpha: Double): this.type = js.native 32 | def alpha(): Double = js.native 33 | def alphaMin(min: Double): this.type = js.native 34 | def alphaMin(): Double = js.native 35 | def alphaDecay(decay: Double): this.type = js.native 36 | def alphaDecay(): Double = js.native 37 | def alphaTarget(target: Double): this.type = js.native 38 | def alphaTarget(): Double = js.native 39 | def velocityDecay(decay: Double): this.type = js.native 40 | def velocityDecay(): Double = js.native 41 | 42 | def force(name: String, force: Force[N]): this.type = js.native 43 | def force(name: String): Force[N] = js.native 44 | 45 | def find(x: Double, y: Double): js.UndefOr[N] = js.native 46 | def find(x: Double, y: Double, radius: Double): js.UndefOr[N] = js.native 47 | 48 | def on(typenames: String, listener: js.ThisFunction0[Simulation[N], Any]): this.type = js.native 49 | def on(typenames: String, listener: ListenerFunction0): this.type = js.native 50 | def on(typenames: String): this.type = js.native 51 | } 52 | trait Force[N <: SimulationNode] extends js.Object { 53 | def force(alpha: Double): Unit 54 | def initialize(nodes: js.Array[N]): Unit 55 | } 56 | 57 | @js.native 58 | trait ForceImpl[N <: SimulationNode] extends Force[N] { 59 | def force(alpha: Double): Unit = js.native 60 | def initialize(nodes: js.Array[N]): Unit = js.native 61 | } 62 | 63 | @js.native 64 | trait Centering[N <: SimulationNode] extends ForceImpl[N] { 65 | def x(x: Double): this.type = js.native 66 | def y(y: Double): this.type = js.native 67 | def x(): Double = js.native 68 | def y(): Double = js.native 69 | } 70 | 71 | @js.native 72 | trait PositioningX[N <: SimulationNode] extends ForceImpl[N] { 73 | def x(x: Double): this.type = js.native 74 | def strength(strength: Double): this.type = js.native 75 | } 76 | 77 | @js.native 78 | trait PositioningY[N <: SimulationNode] extends ForceImpl[N] { 79 | def y(y: Double): this.type = js.native 80 | def strength(strength: Double): this.type = js.native 81 | } 82 | 83 | @js.native 84 | trait ManyBody[N <: SimulationNode] extends ForceImpl[N] { 85 | def strength(strength: Double): this.type = js.native 86 | def strength(strength: js.Function1[N, Double]): this.type = js.native 87 | def theta(theta: Double): this.type = js.native 88 | def theta(): Double = js.native 89 | def distanceMin(distance: Double): this.type = js.native 90 | def distanceMin(): Double = js.native 91 | def distanceMax(distance: Double): this.type = js.native 92 | def distanceMax(): Double = js.native 93 | } 94 | 95 | @js.native 96 | trait Collision[N <: SimulationNode] extends ForceImpl[N] { 97 | def radius(radius: js.Function1[N, Double]): this.type = js.native 98 | def strength(strength: Double): this.type = js.native 99 | } 100 | 101 | @js.native 102 | trait Link[N <: SimulationNode, L <: SimulationLink[_ <: N, _ <: N]] extends ForceImpl[N] { 103 | def distance(distance: Double): this.type = js.native 104 | def distance(distance: js.Function1[L, Double]): this.type = js.native 105 | def strength(strength: Double): this.type = js.native 106 | def strength(strength: js.Function1[L, Double]): this.type = js.native 107 | def links(links: js.Array[L]): this.type = js.native 108 | } 109 | 110 | } 111 | 112 | @JSExportAll 113 | trait SimulationNode { 114 | def index: js.UndefOr[Int] 115 | def index_=(newIndex: js.UndefOr[Int]): Unit 116 | def x: js.UndefOr[Double] 117 | def x_=(newX: js.UndefOr[Double]): Unit 118 | def y: js.UndefOr[Double] 119 | def y_=(newY: js.UndefOr[Double]): Unit 120 | def vx: js.UndefOr[Double] 121 | def vx_=(newVX: js.UndefOr[Double]): Unit 122 | def vy: js.UndefOr[Double] 123 | def vy_=(newVX: js.UndefOr[Double]): Unit 124 | def fx: js.UndefOr[Double] 125 | def fx_=(newFX: js.UndefOr[Double]): Unit 126 | def fy: js.UndefOr[Double] 127 | def fy_=(newFX: js.UndefOr[Double]): Unit 128 | } 129 | trait SimulationNodeImpl extends SimulationNode { 130 | var index: js.UndefOr[Int] = js.undefined 131 | 132 | var x: js.UndefOr[Double] = js.undefined 133 | var y: js.UndefOr[Double] = js.undefined 134 | var vx: js.UndefOr[Double] = js.undefined 135 | var vy: js.UndefOr[Double] = js.undefined 136 | var fx: js.UndefOr[Double] = js.undefined 137 | var fy: js.UndefOr[Double] = js.undefined 138 | } 139 | 140 | @JSExportAll 141 | trait SimulationLink[S <: SimulationNode, T <: SimulationNode] { 142 | def index: js.UndefOr[Int] 143 | def index_=(newIndex: js.UndefOr[Int]): Unit 144 | 145 | def source: S 146 | def target: T 147 | } 148 | 149 | trait SimulationLinkImpl[S <: SimulationNode, T <: SimulationNode] extends SimulationLink[S, T] { 150 | var index: js.UndefOr[Int] = js.undefined 151 | 152 | // var source: S = _ 153 | // var target: T = _ 154 | } 155 | -------------------------------------------------------------------------------- /src/main/scala/Hierarchy.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation.{JSExportAll, JSImport} 5 | 6 | /** @see 7 | * [[https://github.com/d3/d3-hierarchy]] 8 | * @since January, 9 | * 2021 10 | * @author 11 | * Michael Ahlers 12 | */ 13 | @JSImport("d3-hierarchy", JSImport.Namespace) 14 | @js.native 15 | object d3hierarchy extends js.Object { 16 | 17 | /** @see [[https://github.com/d3/d3-hierarchy#hierarchy]] */ 18 | def hierarchy[Datum](data: Datum): Hierarchy[Datum] = js.native 19 | 20 | /** @see [[https://github.com/d3/d3-hierarchy#hierarchy]] */ 21 | def hierarchy[Datum](data: Datum, children: js.Function1[Datum, js.Array[Datum]]): Hierarchy[Datum] = js.native 22 | 23 | /** @see [[https://github.com/d3/d3-hierarchy#pack]] */ 24 | def pack[Datum](): Pack[Datum] = js.native 25 | 26 | /** @see [[hierarchy]] */ 27 | @js.native 28 | trait Hierarchy[Datum] extends js.Object { 29 | 30 | def data: Datum = js.native 31 | def depth: js.UndefOr[Int] = js.native 32 | def height: js.UndefOr[Int] = js.native 33 | def parent: js.UndefOr[this.type] = js.native 34 | def children: js.UndefOr[js.Array[this.type]] = js.native 35 | 36 | /** @see [[https://github.com/d3/d3-hierarchy#node_ancestors]] */ 37 | def ancestors(): js.Array[this.type] = js.native 38 | 39 | /** @see [[https://github.com/d3/d3-hierarchy#node_descendants]] */ 40 | def descendants(): js.Array[this.type] = js.native 41 | 42 | /** @see [[https://github.com/d3/d3-hierarchy#node_leaves]] */ 43 | def leaves(): js.Array[this.type] = js.native 44 | 45 | // /** @see [[https://github.com/d3/d3-hierarchy#node_find]] */ 46 | // def find(filter: ???): ??? = js.native 47 | 48 | /** @see [[https://github.com/d3/d3-hierarchy#node_path]] */ 49 | def path(target: Datum): js.Array[this.type] = js.native 50 | 51 | /** @see [[https://github.com/d3/d3-hierarchy#node_links]] */ 52 | def links(): js.Array[this.type] = js.native 53 | 54 | // /** @see [[https://github.com/d3/d3-hierarchy#node_sum]] */ 55 | // def sum(value: ???): ??? = js.native 56 | 57 | /** @see [[https://github.com/d3/d3-hierarchy#node_count]] */ 58 | def count(): Int = js.native 59 | 60 | /** @see [[https://github.com/d3/d3-hierarchy#node_sort]] */ 61 | def sort(compare: js.Function2[this.type, this.type, Int]): this.type = js.native 62 | 63 | /** @see [[https://github.com/d3/d3-hierarchy#node_each]] */ 64 | def each(function: js.Function1[this.type, Unit]): this.type = js.native 65 | 66 | // /** @see [[https://github.com/d3/d3-hierarchy#node_each]] */ 67 | // def each(function: js.Function1[this.type, Unit], that: ???): this.type = js.native 68 | 69 | /** @see [[https://github.com/d3/d3-hierarchy#node_eachAfter]] */ 70 | def eachAfter(function: js.Function1[this.type, Unit]): this.type = js.native 71 | 72 | // /** @see [[https://github.com/d3/d3-hierarchy#node_eachAfter]] */ 73 | // def eachAfter(function: js.Function1[this.type, Unit], that: ???): this.type = js.native 74 | 75 | /** @see [[https://github.com/d3/d3-hierarchy#node_eachBefore]] */ 76 | def eachBefore(function: js.Function1[this.type, Unit]): this.type = js.native 77 | 78 | // /** @see [[https://github.com/d3/d3-hierarchy#node_eachBefore]] */ 79 | // def eachBefore(function: js.Function1[this.type, Unit], that: ???): this.type = js.native 80 | 81 | /** @see [[https://github.com/d3/d3-hierarchy#node_copy]] */ 82 | def copy(): this.type = js.native 83 | 84 | } 85 | 86 | @js.native 87 | trait Packed extends js.Object { self: Hierarchy[_] => 88 | def x: js.UndefOr[Double] = js.native 89 | def y: js.UndefOr[Double] = js.native 90 | def r: js.UndefOr[Double] = js.native 91 | } 92 | 93 | /** @see 94 | * [[pack]] 95 | * @see 96 | * [[https://github.com/d3/d3-hierarchy#pack]] 97 | */ 98 | @js.native 99 | trait Pack[Datum] extends js.Function1[Hierarchy[Datum], Hierarchy[Datum] with Packed] { 100 | 101 | /** @see [[https://github.com/d3/d3-hierarchy#pack_radius]] */ 102 | def radius(): Double = js.native 103 | 104 | /** @see [[https://github.com/d3/d3-hierarchy#pack_radius]] */ 105 | def radius(radius: js.Function1[Hierarchy[Datum], js.UndefOr[Double]]): this.type = js.native 106 | 107 | // /** @see [[https://github.com/d3/d3-hierarchy#pack_radius]] */ 108 | // def radius(radius: Double): this.type = js.native 109 | 110 | /** @see [[https://github.com/d3/d3-hierarchy#pack_size]] */ 111 | def size(): js.Array[Int] = js.native 112 | 113 | /** @see [[https://github.com/d3/d3-hierarchy#pack_size]] */ 114 | def size(size: js.Array[Int]): this.type = js.native 115 | 116 | /** @see [[https://github.com/d3/d3-hierarchy#pack_padding]] */ 117 | def padding(): js.Function1[Hierarchy[Datum], Double] = js.native 118 | 119 | /** @see [[https://github.com/d3/d3-hierarchy#pack_padding]] */ 120 | def padding(padding: js.Function1[Hierarchy[Datum], Double]): this.type = js.native 121 | 122 | /** @see [[https://github.com/d3/d3-hierarchy#pack_padding]] */ 123 | def padding(padding: Double): this.type = js.native 124 | 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/scala/Polygon.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | 7 | // https://github.com/d3/d3-polygon 8 | @JSImport("d3-polygon", JSImport.Namespace) 9 | @js.native 10 | object d3polygon extends js.Object { 11 | type Point = js.Tuple2[Double, Double] 12 | type Polygon = js.Array[Point] 13 | 14 | def polygonArea(polygon: Polygon): Double = js.native 15 | def polygonCentroid(polygon: Polygon): Point = js.native 16 | def polygonHull(points: Polygon): Polygon | Null = js.native 17 | def polygonContains(polygon: Polygon, point: Point): Boolean = js.native 18 | def polygonLength(polygon: Polygon): Boolean = js.native 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/Quadtree.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | import org.scalajs.dom 7 | 8 | // https://github.com/d3/d3-quadtree 9 | @JSImport("d3-quadtree", JSImport.Namespace) 10 | @js.native 11 | object d3quadtree extends js.Object { 12 | def quadtree[Datum](): Quadtree[Datum] = js.native 13 | def quadtree[Datum](data: js.Array[Datum]): Quadtree[Datum] = js.native 14 | def quadtree[Datum]( 15 | data: js.Array[Datum], 16 | x: js.Function1[Datum, Double], 17 | y: js.Function1[Datum, Double], 18 | ): Quadtree[Datum] = js.native 19 | 20 | @js.native 21 | trait Quadtree[Datum] extends js.Object { 22 | def x(x: js.Function1[Datum, Double]): Quadtree[Datum] = js.native 23 | def x(): js.Function1[Datum, Double] = js.native 24 | def y(y: js.Function1[Datum, Double]): Quadtree[Datum] = js.native 25 | def y(): js.Function1[Datum, Double] = js.native 26 | def add(datum: Datum): Quadtree[Datum] = js.native 27 | def addAll[NewDatum](data: js.Array[NewDatum]): Quadtree[NewDatum] = js.native 28 | def remove(datum: Datum): Quadtree[Datum] = js.native 29 | def root: QuadtreeNode[Datum] = js.native 30 | def data: js.Array[Datum] = js.native 31 | def size: Int = js.native 32 | def find(x: Double, y: Double): Datum = js.native 33 | def find(x: Double, y: Double, radius: Double): Datum = js.native 34 | def visit(callback: js.Function5[QuadtreeNode[Datum], Double, Double, Double, Double, Boolean]): Quadtree[Datum] = 35 | js.native 36 | def visitAfter(callback: js.Function5[QuadtreeNode[Datum], Double, Double, Double, Double, Any]): Quadtree[Datum] = 37 | js.native 38 | def copy: Quadtree[Datum] = js.native 39 | } 40 | 41 | @js.native 42 | sealed trait QuadtreeNode[Datum] extends js.Any { 43 | def length: js.UndefOr[Int] = js.native 44 | def apply(index: Int): QuadtreeNode[Datum] = js.native 45 | def data: Datum = js.native 46 | def next: js.UndefOr[QuadtreeNode[Datum]] = js.native 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/scala/Scale.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | 7 | // https://github.com/d3/d3-scale 8 | 9 | @JSImport("d3-scale", JSImport.Namespace) 10 | @js.native 11 | object d3scale extends js.Object { 12 | def scaleLinear(): LinearScale = js.native 13 | def scaleLog(): LogScale = js.native 14 | def scaleTime(): TimeScale = js.native 15 | def scaleBand[T, R](): BandScale[T, R] = js.native 16 | def scaleOrdinal[T, R](values: js.Array[String]): OrdinalScale[T, R] = js.native 17 | def schemeCategory10: js.Array[String] = js.native 18 | def schemeCategory20: js.Array[String] = js.native 19 | def schemeCategory20b: js.Array[String] = js.native 20 | def schemeCategory20c: js.Array[String] = js.native 21 | 22 | @js.native 23 | trait Scale extends js.Object 24 | 25 | @js.native 26 | trait ContinuousScale[S <: ContinuousScale[S]] extends Scale { 27 | def apply(value: Double): Double = js.native 28 | def invert(value: Double): Double = js.native 29 | def domain(domain: js.Array[Double]): S = js.native 30 | def range(range: js.Array[Double]): S = js.native 31 | def rangeRound(range: js.Array[Double]): S = js.native 32 | } 33 | 34 | @js.native 35 | trait LogScale extends ContinuousScale[LogScale] { 36 | def base(base: Double): LogScale = js.native 37 | } 38 | 39 | @js.native 40 | trait LinearScale extends ContinuousScale[LinearScale] {} 41 | 42 | @js.native 43 | trait TimeScale extends ContinuousScale[TimeScale] { 44 | def apply(value: js.Date): Double = js.native 45 | def domain(domain: js.Array[js.Date]): TimeScale = js.native 46 | } 47 | 48 | @js.native 49 | trait OrdinalScale[T, R] extends Scale { 50 | def domain(values: js.Array[T]): this.type = js.native 51 | def domain(): js.Array[T] = js.native 52 | def range(): this.type = js.native 53 | def range(range: js.Array[R]): this.type = js.native 54 | def apply(string: String): js.Any = js.native 55 | } 56 | 57 | @js.native 58 | trait BandScale[T, R] extends OrdinalScale[T, R] { 59 | def apply(value: T): js.Any = js.native 60 | def bandwidth(): Double = js.native 61 | def rangeRound(range: js.Array[R]): this.type = js.native 62 | def padding(padding: Double): this.type = js.native 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/scala/Selection.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | import org.scalajs.dom 7 | import d3._ 8 | 9 | // https://github.com/d3/d3-selection 10 | @JSImport("d3-selection", JSImport.Namespace) 11 | @js.native 12 | object d3selection extends js.Object { 13 | def select(selector: String): Selection[dom.EventTarget] = js.native // TODO: Return type correct? 14 | def select(node: dom.EventTarget): Selection[dom.EventTarget] = js.native // TODO: Return type correct? 15 | var event: dom.Event with BaseEvent = js.native 16 | def mouse(container: dom.EventTarget): js.Array[Double] = js.native 17 | 18 | @js.native 19 | trait BaseSelection[Datum, T <: BaseSelection[Datum, T]] extends BaseDom[Datum, T] { 20 | def append(`type`: String): T = js.native 21 | def append(`type`: js.Function0[dom.EventTarget]): T = js.native 22 | def append(`type`: js.Function1[Datum, dom.EventTarget]): T = js.native 23 | 24 | def on(typenames: String, listener: ListenerFunction0): T = js.native 25 | def on(typenames: String, listener: ListenerFunction1): T = js.native 26 | def on(typenames: String, listener: ListenerFunction2): T = js.native 27 | 28 | def data(): js.Array[Datum] = js.native 29 | def data[NewDatum <: Datum](data: js.Array[NewDatum]): Update[NewDatum] = js.native 30 | // TODO: d3 doc says that key can be a ThisFunction with this as the current node. It Doesn't work here... 31 | def data[NewDatum <: Datum, R](data: js.Array[NewDatum], key: ValueFunction0[R]): Update[NewDatum] = js.native 32 | def data[NewDatum <: Datum, R](data: js.Array[NewDatum], key: ValueFunction1[R]): Update[NewDatum] = js.native 33 | def data[NewDatum <: Datum, R](data: js.Array[NewDatum], key: ValueFunction2[R]): Update[NewDatum] = js.native 34 | def data[NewDatum <: Datum, R](data: js.Array[NewDatum], key: ValueFunction3[R]): Update[NewDatum] = js.native 35 | def data[NewDatum <: Datum, R](key: ValueFunction1[R]): Update[NewDatum] = js.native 36 | 37 | def each[C <: CurrentDom](function: ListenerThisFunction0[C]): Unit = js.native 38 | def each[C <: CurrentDom](function: ListenerThisFunction1[C]): Unit = js.native 39 | def each[C <: CurrentDom](function: ListenerThisFunction2[C]): Unit = js.native 40 | def each[C <: CurrentDom](function: ListenerThisFunction3[C]): Unit = js.native 41 | 42 | def size(): Int = js.native 43 | } 44 | 45 | @js.native 46 | trait BaseDom[Datum, T <: BaseDom[Datum, T]] extends js.Object { 47 | type ValueFunction0[Return] = js.Function0[Return] 48 | type ValueFunction1[Return] = js.Function1[Datum, Return] 49 | type ValueFunction2[Return] = js.Function2[Datum, Index, Return] 50 | type ValueFunction3[Return] = js.Function3[Datum, Index, Group, Return] 51 | 52 | type ListenerFunction0 = ValueFunction0[Unit] 53 | type ListenerFunction1 = ValueFunction1[Unit] 54 | type ListenerFunction2 = ValueFunction2[Unit] 55 | type ListenerFunction3 = ValueFunction3[Unit] 56 | 57 | type ValueThisFunction0[C <: CurrentDom, Return] = js.ThisFunction0[C, Return] 58 | type ValueThisFunction1[C <: CurrentDom, Return] = js.ThisFunction1[C, Datum, Return] 59 | type ValueThisFunction2[C <: CurrentDom, Return] = js.ThisFunction2[C, Datum, Index, Return] 60 | type ValueThisFunction3[C <: CurrentDom, Return] = js.ThisFunction3[C, Datum, Index, Group, Return] 61 | 62 | type ListenerThisFunction0[C <: CurrentDom] = ValueThisFunction0[C, Unit] 63 | type ListenerThisFunction1[C <: CurrentDom] = ValueThisFunction1[C, Unit] 64 | type ListenerThisFunction2[C <: CurrentDom] = ValueThisFunction2[C, Unit] 65 | type ListenerThisFunction3[C <: CurrentDom] = ValueThisFunction3[C, Unit] 66 | 67 | def style(name: String, value: String): T = js.native 68 | def style[R](name: String, value: ValueFunction0[R]): T = js.native 69 | def style[R](name: String, value: ValueFunction1[R]): T = js.native 70 | def style[R](name: String, value: ValueFunction2[R]): T = js.native 71 | def style[R](name: String, value: ValueFunction3[R]): T = js.native 72 | 73 | def style[R](name: String, value: ValueThisFunction0[CurrentDom, R]): T = 74 | js.native // no C type parameter here, since it would be ambiguous with ValueFunction1. TODO: is there a better solution? 75 | def style[C <: CurrentDom, R](name: String, value: ValueThisFunction1[C, R]): T = js.native 76 | def style[C <: CurrentDom, R](name: String, value: ValueThisFunction2[C, R]): T = js.native 77 | def style[C <: CurrentDom, R](name: String, value: ValueThisFunction3[C, R]): T = js.native 78 | 79 | def classed(names: String, value: Boolean): T = js.native 80 | def classed(names: String, value: ValueFunction0[Boolean]): T = js.native 81 | def classed(names: String, value: ValueFunction1[Boolean]): T = js.native 82 | def classed(names: String, value: ValueFunction2[Boolean]): T = js.native 83 | def classed(names: String, value: ValueFunction3[Boolean]): T = js.native 84 | 85 | def attr(name: String, value: String): T = js.native 86 | def attr(name: String, value: Double): T = js.native 87 | def attr(name: String, value: Boolean): T = js.native 88 | def attr[R](name: String, value: ValueFunction1[R]): T = js.native 89 | def attr[R](name: String, value: ValueFunction2[R]): T = js.native 90 | 91 | def text(): String = js.native 92 | def text(value: String): T = js.native 93 | def text[R](value: ValueFunction0[R]): T = js.native 94 | def text[R](value: ValueFunction1[R]): T = js.native 95 | def text[R](value: ValueFunction2[R]): T = js.native 96 | 97 | def html(): String = js.native 98 | def html(value: String): T = js.native 99 | def html[R](value: ValueFunction0[R]): T = js.native 100 | def html[R](value: ValueFunction1[R]): T = js.native 101 | 102 | def call(func: js.Function, args: js.Any*): T = js.native 103 | def remove(): T = js.native 104 | } 105 | 106 | @js.native 107 | trait Selection[Datum] extends BaseSelection[Datum, Selection[Datum]] { 108 | def select[SelData](selector: String): Selection[SelData] = js.native 109 | def selectAll[SelData](selector: String): Selection[SelData] = js.native 110 | def node(): dom.EventTarget = js.native 111 | def merge(other: Update[Datum]): Selection[Datum] = js.native 112 | 113 | /** @see [[d3transition]] */ 114 | def transition(): Transition[Datum] = js.native 115 | 116 | /** @see [[d3transition]] */ 117 | def transition(name: String): Transition[Datum] = js.native 118 | } 119 | 120 | @js.native 121 | trait Update[Datum] extends BaseSelection[Datum, Update[Datum]] { 122 | def enter(): Enter[Datum] = js.native 123 | def exit(): Selection[Datum] = js.native 124 | } 125 | 126 | @js.native 127 | trait Enter[Datum] extends js.Object { 128 | def append(name: String): Selection[Datum] = js.native 129 | def append(`type`: js.Function0[dom.EventTarget]): Selection[Datum] = js.native 130 | def append(`type`: js.Function1[Datum, dom.EventTarget]): Selection[Datum] = js.native 131 | 132 | def append(name: js.Function3[Datum, Double, Double, dom.EventTarget]): Selection[Datum] = js.native 133 | 134 | def size(): Int = js.native 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/scala/Shape.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | 7 | import org.scalajs.dom.CanvasRenderingContext2D 8 | 9 | // https://github.com/d3/d3-shape 10 | @JSImport("d3-shape", JSImport.Namespace) 11 | @js.native 12 | object d3shape extends js.Object { 13 | def pie(): PieGenerator = js.native 14 | def arc(): ArcGenerator = js.native 15 | def line(): LineGenerator = js.native 16 | def curveBasisClosed: CurveFactory = js.native 17 | def curveCardinalClosed: CurveFactory = js.native 18 | def curveCatmullRomClosed: CurveCatmullRomFactory = js.native 19 | def curveBasis: CurveFactory = js.native 20 | def curveCardinal: CurveFactory = js.native 21 | def curveCatmullRom: CurveCatmullRomFactory = js.native 22 | def curveLinear: CurveFactory = js.native 23 | def curveLinearClosed: CurveFactory = js.native 24 | def curveBundle: CurveBundleFactory = js.native 25 | def curveBundleClosed: CurveBundleFactory = js.native 26 | 27 | @js.native 28 | trait BaseGenerator[G <: BaseGenerator[G]] extends js.Object { 29 | def context(context: CanvasRenderingContext2D): G = js.native 30 | def context(): CanvasRenderingContext2D = js.native 31 | } 32 | 33 | @js.native 34 | trait BaseLineGenerator[G <: BaseLineGenerator[G]] extends js.Object with BaseGenerator[G] { 35 | def curve(curve: CurveFactory): G = js.native 36 | } 37 | 38 | @js.native 39 | trait LineGenerator extends BaseLineGenerator[LineGenerator] { 40 | def apply(data: js.Array[js.Tuple2[Double, Double]]): js.UndefOr[String] = js.native 41 | } 42 | 43 | @js.native 44 | trait CurveFactory extends js.Object 45 | 46 | @js.native 47 | trait CurveCatmullRomFactory extends CurveFactory { 48 | def alpha(alpha: Double): CurveCatmullRomFactory = js.native 49 | } 50 | 51 | @js.native 52 | trait CurveBundleFactory extends CurveFactory { 53 | def beta(beta: Double): CurveBundleFactory = js.native 54 | } 55 | 56 | @js.native 57 | trait PieGenerator extends js.Object { 58 | def value(value: Double): PieGenerator = js.native 59 | def padAngle(angle: Double): PieGenerator = js.native 60 | def apply[Datum](data: js.Array[Datum]): js.Array[PieArcDatum[Datum]] = js.native 61 | } 62 | 63 | @js.native 64 | trait PieArcDatum[Datum] extends ArcDatum { 65 | def data: Datum = js.native 66 | def value: Double = js.native 67 | def index: Int = js.native 68 | def startAngle: Double = js.native 69 | def endAngle: Double = js.native 70 | def padAngle: Double = js.native 71 | } 72 | 73 | @js.native 74 | trait ArcDatum extends js.Object 75 | 76 | @js.native 77 | trait BaseArcGenerator[G <: BaseArcGenerator[G]] extends js.Object with BaseGenerator[G] { 78 | def innerRadius(radius: Double): G = js.native 79 | def outerRadius(radius: Double): G = js.native 80 | def cornerRadius(radius: Double): G = js.native 81 | } 82 | 83 | @js.native 84 | trait ArcGenerator extends BaseArcGenerator[ArcGenerator] { 85 | def apply[T <: ArcDatum](arguments: T): String = js.native 86 | def centroid[T <: ArcDatum](arguments: T): js.Tuple2[Double, Double] = js.native 87 | } 88 | 89 | @js.native 90 | trait ArcGeneratorWithContext extends BaseArcGenerator[ArcGeneratorWithContext] { 91 | def apply[T <: ArcDatum](arguments: T): Unit = js.native 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/scala/Time.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | 7 | // https://github.com/d3/d3-time 8 | 9 | @JSImport("d3-time", JSImport.Namespace) 10 | @js.native 11 | object d3time extends js.Object { 12 | def timeMillisecond: Interval = js.native 13 | def utcMillisecond: Interval = js.native 14 | def timeSecond: Interval = js.native 15 | def utcSecond: Interval = js.native 16 | def timeMinute: Interval = js.native 17 | def utcMinute: Interval = js.native 18 | def timeHour: Interval = js.native 19 | def utcHour: Interval = js.native 20 | def timeDay: Interval = js.native 21 | def utcDay: Interval = js.native 22 | def timeWeek: Interval = js.native 23 | def utcWeek: Interval = js.native 24 | 25 | def timeSunday: Interval = js.native 26 | def utcSunday: Interval = js.native 27 | def timeMonday: Interval = js.native 28 | def utcMonday: Interval = js.native 29 | def timeTuesday: Interval = js.native 30 | def utcTuesday: Interval = js.native 31 | def timeWednesday: Interval = js.native 32 | def utcWednesday: Interval = js.native 33 | def timeThursday: Interval = js.native 34 | def utcThursday: Interval = js.native 35 | def timeFriday: Interval = js.native 36 | def utcFriday: Interval = js.native 37 | def timeSaturday: Interval = js.native 38 | def utcSaturday: Interval = js.native 39 | 40 | def timeMonth: Interval = js.native 41 | def utcMonth: Interval = js.native 42 | def timeYear: Interval = js.native 43 | def utcYear: Interval = js.native 44 | 45 | @js.native 46 | trait Interval extends js.Object { 47 | def apply(d: js.Date): js.Date = js.native 48 | def floor(d: js.Date): js.Date = js.native 49 | def round(d: js.Date): js.Date = js.native 50 | def ceil(d: js.Date): js.Date = js.native 51 | def offset(date: js.Date): js.Date = js.native 52 | def offset(date: js.Date, step: Double): js.Date = js.native 53 | def range(start: js.Date, stop: js.Date): js.Array[js.Date] = js.native 54 | def range(start: js.Date, stop: js.Date, step: Double): js.Array[js.Date] = js.native 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/scala/Transition.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import org.scalajs.dom 4 | 5 | import scala.scalajs.js 6 | import scala.scalajs.js.annotation._ 7 | 8 | /** @see [[https://github.com/d3/d3-transition]] */ 9 | @JSImport("d3-transition", JSImport.Namespace) 10 | @js.native 11 | object d3transition extends js.Object { 12 | 13 | /** @see [[https://github.com/d3/d3-transition#transition_delay]] */ 14 | def delay(value: Double): Transition[dom.EventTarget] = js.native 15 | 16 | /** @see [[https://github.com/d3/d3-transition#transition_duration]] */ 17 | def duration(value: Double): Transition[dom.EventTarget] = js.native 18 | 19 | /** @see [[https://github.com/d3/d3-transition#transition]] */ 20 | def transition(): Transition[dom.EventTarget] = js.native 21 | 22 | /** @see [[https://github.com/d3/d3-transition#transition]] */ 23 | def transition(name: String): Transition[dom.EventTarget] = js.native 24 | 25 | @js.native 26 | trait Transition[Datum] extends js.Object { 27 | 28 | /** @see [[https://github.com/d3/d3-transition#transition_delay]] */ 29 | def delay(value: Double): Transition[Datum] = js.native 30 | 31 | /** @see [[https://github.com/d3/d3-transition#transition_duration]] */ 32 | def duration(value: Double): Transition[Datum] = js.native 33 | 34 | /** @see [[https://github.com/d3/d3-transition#transition_empty]] */ 35 | def empty(): Boolean = js.native 36 | 37 | /** @see [[https://github.com/d3/d3-transition#transition_nodes]] */ 38 | def nodes(): js.Array[dom.EventTarget] = js.native 39 | 40 | /** @see [[https://github.com/d3/d3-transition#transition_node]] */ 41 | def node(): dom.EventTarget = js.native 42 | 43 | /** @see [[https://github.com/d3/d3-transition#transition_size]] */ 44 | def size(): Int = js.native 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/scala/Zoom.scala: -------------------------------------------------------------------------------- 1 | package d3v4 2 | 3 | import scalajs.js 4 | import scalajs.js.{undefined, `|`} 5 | import scala.scalajs.js.annotation._ 6 | import org.scalajs.dom 7 | import d3._ 8 | 9 | // https://github.com/d3/d3-zoom 10 | @JSImport("d3-zoom", JSImport.Namespace) 11 | @js.native 12 | object d3zoom extends js.Object { 13 | def zoomIdentity: Transform = js.native 14 | def zoom[Datum](): ZoomBehavior[Datum] = js.native 15 | 16 | @js.native 17 | trait Transform extends js.Object { 18 | def x: Double = js.native 19 | def y: Double = js.native 20 | def k: Double = js.native 21 | override def toString(): String = js.native 22 | 23 | def scale(k: Double | js.UndefOr[Double]): Transform 24 | def translate(x: Double | js.UndefOr[Double], y: Double | js.UndefOr[Double]): Transform 25 | def apply(point: js.Array[Double]): js.Array[Double] = js.native 26 | def applyX(x: Double | js.UndefOr[Double]): Double = js.native 27 | def applyY(x: Double | js.UndefOr[Double]): Double = js.native 28 | def invert(point: js.Array[Double]): js.Array[Double] = js.native 29 | def invertX(x: Double | js.UndefOr[Double]): Double = js.native 30 | def invertY(x: Double | js.UndefOr[Double]): Double = js.native 31 | def rescaleX[S <: ContinuousScale[S]](x: ContinuousScale[S]): S = js.native 32 | def rescaleY[S <: ContinuousScale[S]](y: ContinuousScale[S]): S = js.native 33 | } 34 | 35 | @js.native 36 | trait ZoomEvent extends BaseEvent { 37 | def transform: Transform = js.native 38 | } 39 | 40 | @js.native 41 | trait ZoomBehavior[Datum] extends js.Function1[Selection[Datum], Unit] { 42 | def on(typenames: String, listener: ListenerFunction0): ZoomBehavior[Datum] = js.native 43 | def scaleExtent(extent: js.Array[Double]): ZoomBehavior[Datum] = js.native 44 | def scaleExtent(): js.Array[Double] = js.native 45 | def transform(selection: Selection[Datum], transform: Transform): Transform = js.native 46 | def transform(transition: Transition[Datum], transform: Transform): Transform = js.native 47 | def translateBy(selection: Selection[Datum], x: Double, y: Double): Transform = js.native 48 | def scaleBy(selection: Selection[Datum], k: Double): Transform = js.native 49 | def scaleTo(selection: Selection[Datum], k: Double): Transform = js.native 50 | def clickDistance(distance: Double): ZoomBehavior[Datum] = js.native 51 | def clickDistance(): Double = js.native 52 | } 53 | } 54 | --------------------------------------------------------------------------------