Skip to content

turansky/yfiles-kotlin

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.3 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