- Resolve inheritance problems
- Optimize yFiles imports
- while ES modules not supported
- Check inheritance rules on the fly
- Highlight binding syntax
- Generation
- YClass
- Factory methods
- Quick interface implementation
- Flags
- Extensions
for
loop- Observable
- TimeSpan extensions
- Resources Defaults
- KDoc
- Run
./gradlew build
- Check source folders
Declarations | Source folder |
---|---|
yFiles for HTML | yfiles-kotlin |
VSDX Export | vsdx-kotlin |
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
No Xcode or CLT version detected!
- FormacOS Catalina
// JS: IVisibilityTestable.$class
val clazz = IVisibilityTestable.yclass
Boolean.yclass // YBoolean.$class
Double.yclass // YNumber.$class
Int.yclass // YNumber.$class
String.yclass // YString.$class
fun(o: Any?) {
val isNode: Boolean = o yIs INode
val optNode: INode? = o yOpt INode
val node: INode = o yAs INode
}
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'
val clazz: YClass<IVisibilityTestable> = IVisibilityTestable.yclass
// strict lookup
val visibilityTestable: IVisibilityTestable = renderer.lookup(IVisibilityTestable.yclass)
val boundsProvider: IBoundsProvider = renderer.lookup(IBoundsProvider.yclass)
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
}
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)
Some yFiles enums are marked as flags
.
- Use
or
infix method to combineflags
- Use
in
operator to check ifflags
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
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()
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}") }
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}") }
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')
}
}
}
val c: TimeSpan = 2.hours
val o: TimeSpan = 0.minutes
val d: TimeSpan = 1.seconds
val e: TimeSpan = 3.milliseconds
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
}
Generated!
KT-32815
- Broken links with double anchor#
IDEA-219818
- Broken links with double anchor#
KT-32640
- Broken markdown links in@see
blockKT-32720
-@see
is recommended?