Skip to content

Kotlin/JS support for yFiles

License

Notifications You must be signed in to change notification settings

turansky/yfiles-kotlin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

876c865 · Feb 24, 2025
Jan 2, 2025
Oct 19, 2019
Aug 3, 2024
Jun 14, 2020
Feb 24, 2025
Sep 26, 2024
Sep 26, 2024
Feb 23, 2025
Aug 3, 2024
Feb 24, 2025
Feb 23, 2025
Sep 26, 2024
Feb 24, 2025
Aug 25, 2020
Aug 13, 2019
Feb 24, 2025
Sep 26, 2024
Feb 24, 2025
Aug 3, 2024
Aug 3, 2024
Feb 24, 2025
Sep 26, 2024

Repository files navigation

CI Status Gradle Plugin Portal IntelliJ IDEA Plugin IntelliJ IDEA Plugin Kotlin

Kotlin/JS support for yFiles

  • Resolve inheritance problems
  • Optimize yFiles imports

Table of contents

Generation

  • Run ./gradlew build
  • Check source folders
Declarations Source folder
yFiles for HTML yfiles-kotlin
VSDX Export vsdx-kotlin

Description

JS library yFiles for HTML VSDX Export
Documentation API API
Module yfiles vsdx-export-for-yfiles-for-html
Version 26.0.4 2.3.2
Module format ES6 ES6
Kotlin/JS Declarations yfiles-kotlin vsdx-kotlin
Nullability fixes 3200+ -
Numberability*
Strict Class generic
Trait support**
Operators
Operator aliases

* - Int, Double instead of Number
** - via extension methods

Related issues

YClass

Metadata

// JS: IVisibilityTestable.$class
val clazz = IVisibilityTestable.yclass

Primitive types

Boolean.yclass   // YBoolean.$class
Double.yclass    // YNumber.$class
Int.yclass       // YNumber.$class
String.yclass    // YString.$class

Cast extensions

fun(o: Any?) {
    val isNode: Boolean = o yIs INode

    val optNode: INode? = o yOpt INode

    val node: INode = o yAs INode
}

Lookup extensions

val graph: IGraph = DefaultGraph()
val node = graph.createNode()

// for classes
val t13: TimeSpan = node.lookup()      // reified lookup type
val t14 = node.lookup<TimeSpan>()       // 'TimeSpan?'

val t23: TimeSpan = node.lookupValue()  // reified lookup type
val t24 = node.lookupValue<TimeSpan>()  // 'TimeSpan'

// for interfaces
val h13: IHitTestable = node.lookup()      // reified lookup type
val h14 = node.lookup<IHitTestable>()       // 'IHitTestable?'

val h23: IHitTestable = node.lookupValue()  // reified lookup type
val h24 = node.lookupValue<IHitTestable>()  // 'IHitTestable'

Type parameter

val clazz: YClass<IVisibilityTestable> = IVisibilityTestable.yclass

// strict lookup
val visibilityTestable: IVisibilityTestable = renderer.lookup(IVisibilityTestable.yclass)
val boundsProvider: IBoundsProvider = renderer.lookup(IBoundsProvider.yclass)

Factory methods

Via apply

val layout = HierarchicLayout().apply {
    layoutOrientation = LEFT_TO_RIGHT
    automaticEdgeGrouping = true
    gridSpacing = 20.0
}

Via factory method

val layout = HierarchicLayout {
    layoutOrientation = LEFT_TO_RIGHT
    automaticEdgeGrouping = true
    gridSpacing = 20.0
}

Quick interface implementation

val mode = CreateEdgeInputMode {
    beginHitTestable = IHitTestable { _, location -> location.x > 0.0 }
    endHitTestable = IHitTestable { _, location -> location.x < 0.0 }
}

will be compiled to

const mode = new CreateEdgeInputMode()
mode.beginHitTestable = IHitTestable.from((_, location) => location.x > 0.0)
mode.endHitTestable = IHitTestable.from((_, location) => location.x < 0.0)

Flags

Some yFiles enums are marked as flags.

  • Use or infix method to combine flags
  • Use in operator to check if flags are applied
import yfiles.graph.GraphItemTypes.*
import yfiles.input.GraphViewerInputMode
import yfiles.lang.contains
import yfiles.lang.or

val inputMode = GraphViewerInputMode {
    clickableItems = NODE or EDGE or LABEL
}

val nodesAreClickable = NODE in inputMode.clickableItems // true

Extensions

Most util methods available as extensions only. Graph and LayoutGraph - the most popular receivers.

import yfiles.algorithms.GraphChecker.isAcyclic
import yfiles.algorithms.GraphChecker.isCyclic
import yfiles.algorithms.Trees.isForest

// ...

val graph: Graph = DefaultLayoutGraph()
// JS: GraphChecker.isCyclic(graph)
graph.isCyclic()
// JS: GraphChecker.isAcyclic(graph)
graph.isAcyclic()
// JS: Trees.isForest(graph)
graph.isForest()

for loop

IEnumerable

import yfiles.collections.asSequence
import yfiles.collections.iterator

val graph: IGraph = DefaultGraph()
// ...

// iterator() extension allows for loops for IEnumerable
for (node in graph.nodes) {
    println("Node layout: ${node.layout}")
}

// asSequence() extension
graph.nodes
    .asSequence()
    .forEach { println("Node layout: ${node.layout}") }

ICursor

import yfiles.algorithms.asSequence
import yfiles.algorithms.iterator

val graph: Graph = DefaultLayoutGraph()
// ...

// iterator() extension allows for loops for ICursor
for (node in graph.getNodeCursor()) {
    println("Node index: ${node.index}")
}

// asSequence() extension
graph.getNodeCursor()
    .asSequence()
    .forEach { println("Node index: ${node.index}") }

Observable

import yfiles.graph.observable

class User : Tag {
    var name: String by observable("Frodo")
    var age: Int by observable(50)
}

will have the same effect as

class User {
    #name = 'Frodo'
    #age = 50

    constructor() {
        makeObservable(this)
    }

    get name() {
        return this.#name
    }

    set name(value) {
        if (this.#name !== value) {
            this.#name = value
            this.firePropertyChanged('name')
        }
    }

    get age() {
        return this.#age
    }

    set age(value) {
        if (this.#age !== value) {
            this.#age = value
            this.firePropertyChanged('age')
        }
    }
}
Details

TimeSpan

val c: TimeSpan = 2.hours
val o: TimeSpan = 0.minutes
val d: TimeSpan = 1.seconds
val e: TimeSpan = 3.milliseconds

Resources Defaults

What is resources defaults?

import yfiles.lang.ResourceKeys.COPY
import yfiles.lang.ResourceKeys.COPY_KEY
import yfiles.lang.Resources.invariant
import yfiles.lang.get

fun main() {
    println(invariant[COPY]) // Copy
    println(invariant[COPY_KEY]) // Action+C;Ctrl+Ins
}

KDoc

Generated!

Online Documentation

Example

Related issues