{"id":15662180,"url":"https://github.com/turansky/yfiles-kotlin","last_synced_at":"2025-10-13T23:02:32.861Z","repository":{"id":45838375,"uuid":"80245850","full_name":"turansky/yfiles-kotlin","owner":"turansky","description":"Kotlin/JS support for yFiles","archived":false,"fork":false,"pushed_at":"2025-02-24T01:24:47.000Z","size":25548,"stargazers_count":20,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-30T00:04:15.075Z","etag":null,"topics":["gradle-plugin","idea-plugin","kotlin","kotlin-declarations","kotlin-js","vsdx-export","yfiles"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/turansky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-01-27T21:04:56.000Z","updated_at":"2025-02-24T01:24:50.000Z","dependencies_parsed_at":"2024-10-23T04:09:15.528Z","dependency_job_id":"26b04a4f-a5cf-40f6-a40d-fd9ac6f7e15e","html_url":"https://github.com/turansky/yfiles-kotlin","commit_stats":{"total_commits":3556,"total_committers":3,"mean_commits":"1185.3333333333333","dds":"0.0019685039370078705","last_synced_commit":"078a212163a97b143bf663f61d55ff5cee997337"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/turansky/yfiles-kotlin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turansky%2Fyfiles-kotlin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turansky%2Fyfiles-kotlin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turansky%2Fyfiles-kotlin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turansky%2Fyfiles-kotlin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/turansky","download_url":"https://codeload.github.com/turansky/yfiles-kotlin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turansky%2Fyfiles-kotlin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279017054,"owners_count":26085984,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gradle-plugin","idea-plugin","kotlin","kotlin-declarations","kotlin-js","vsdx-export","yfiles"],"created_at":"2024-10-03T13:30:30.181Z","updated_at":"2025-10-13T23:02:32.855Z","avatar_url":"https://github.com/turansky.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI Status](https://github.com/turansky/yfiles-kotlin/workflows/declarations/badge.svg)](https://github.com/turansky/yfiles-kotlin/actions)\n[![Gradle Plugin Portal](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/com/github/turansky/yfiles/com.github.turansky.yfiles.gradle.plugin/maven-metadata.xml.svg?label=plugin\u0026logo=gradle)](https://plugins.gradle.org/plugin/com.github.turansky.yfiles)\n[![IntelliJ IDEA Plugin](https://img.shields.io/jetbrains/plugin/v/13384-yfiles?label=plugin\u0026logo=intellij-idea)](https://plugins.jetbrains.com/plugin/13384-yfiles/)\n[![IntelliJ IDEA Plugin](https://img.shields.io/jetbrains/plugin/d/13384-yfiles?logo=intellij-idea)](https://plugins.jetbrains.com/plugin/13384-yfiles/)\n[![Kotlin](https://img.shields.io/badge/kotlin-2.1.10-blue.svg?logo=kotlin)](http://kotlinlang.org)\n\n# Kotlin/JS support for yFiles\n\n## [Gradle Plugin](gradle-plugin)\n\n+ Resolve inheritance problems\n+ Optimize yFiles imports\n    + while [ES modules](https://youtrack.jetbrains.com/issue/KT-8373) not supported\n\n## [IDEA Plugin](idea-plugin)\n\n+ Check [inheritance rules](gradle-plugin) on the fly\n+ Highlight binding syntax\n\n## Table of contents\n\n* [Generation](#generation)\n* [YClass](#yclass)\n    * [Metadata](#metadata)\n    * [Primitive types](#primitive-types)\n    * [Cast extensions](#cast-extensions)\n    * [Lookup extensions](#lookup-extensions)\n    * [Type parameter](#type-parameter)\n* [Factory methods](#factory-methods)\n* [Quick interface implementation](#quick-interface-implementation)\n* [Flags](#flags)\n* [Extensions](#extensions)\n* [`for` loop](#for-loop)\n    * [`IEnumerable`](#ienumerable)\n    * [`ICursor`](#icursor)\n* [Observable](#observable)\n* [TimeSpan extensions](#timespan)\n* [Resources Defaults](#resources-defaults)\n* [KDoc](#kdoc)\n    * [Online Documentation](#online-documentation)\n\n## Generation\n\n* Run `./gradlew build`\n* Check source folders\n\n| Declarations                | Source folder                                    |\n| :---                        | :---                                             |\n| [yFiles for HTML][11]       | [`yfiles-kotlin`](yfiles-kotlin/src/main/kotlin) |\n| [VSDX Export][21]           | [`vsdx-kotlin`](vsdx-kotlin/src/main/kotlin)     |\n\n## Description\n\n| JS library                   | [yFiles for HTML][11] |         [VSDX Export][21]         |\n|:-----------------------------|:---------------------:|:---------------------------------:|\n| Documentation                |       [API][12]       |             [API][22]             |\n| Module                       |       `yfiles`        | `vsdx-export-for-yfiles-for-html` |\n| Version                      |       `26.0.4`        |              `2.3.2`              |\n| Module format                |         `ES6`         |               `ES6`               |\n| **Kotlin/JS Declarations**   |  **`yfiles-kotlin`**  |         **`vsdx-kotlin`**         |\n| Nullability fixes            |         3200+         |                 -                 |\n| Numberability*               |           ✔           |                 ✔                 |\n| Strict [`Class`][31] generic |           ✔           |                 ✔                 |\n| Trait support**              |           ✔           |                 ✔                 |\n| Operators                    |           ✔           |                 ✔                 |\n| Operator aliases             |           ✔           |                 ✔                 |\n\n\\* - `Int`, `Double` instead of `Number`\u003cbr\u003e\n\\** - via extension methods\n\n## `YClass`\n\n#### Metadata\n\n```Kotlin\n// JS: IVisibilityTestable.$class\nval clazz = IVisibilityTestable.yclass\n```\n\n#### Primitive types\n\n```Kotlin\nBoolean.yclass   // YBoolean.$class\nDouble.yclass    // YNumber.$class\nInt.yclass       // YNumber.$class\nString.yclass    // YString.$class\n```\n\n#### Cast extensions\n\n```Kotlin\nfun(o: Any?) {\n    val isNode: Boolean = o yIs INode\n\n    val optNode: INode? = o yOpt INode\n\n    val node: INode = o yAs INode\n}\n```\n\n#### Lookup extensions\n\n```Kotlin\nval graph: IGraph = DefaultGraph()\nval node = graph.createNode()\n\n// for classes\nval t13: TimeSpan = node.lookup()      // reified lookup type\nval t14 = node.lookup\u003cTimeSpan\u003e()       // 'TimeSpan?'\n\nval t23: TimeSpan = node.lookupValue()  // reified lookup type\nval t24 = node.lookupValue\u003cTimeSpan\u003e()  // 'TimeSpan'\n\n// for interfaces\nval h13: IHitTestable = node.lookup()      // reified lookup type\nval h14 = node.lookup\u003cIHitTestable\u003e()       // 'IHitTestable?'\n\nval h23: IHitTestable = node.lookupValue()  // reified lookup type\nval h24 = node.lookupValue\u003cIHitTestable\u003e()  // 'IHitTestable'\n```\n\n#### Type parameter\n\n```Kotlin\nval clazz: YClass\u003cIVisibilityTestable\u003e = IVisibilityTestable.yclass\n\n// strict lookup\nval visibilityTestable: IVisibilityTestable = renderer.lookup(IVisibilityTestable.yclass)\nval boundsProvider: IBoundsProvider = renderer.lookup(IBoundsProvider.yclass)\n```\n\n## Factory methods\n\nVia `apply`\n\n```Kotlin\nval layout = HierarchicLayout().apply {\n    layoutOrientation = LEFT_TO_RIGHT\n    automaticEdgeGrouping = true\n    gridSpacing = 20.0\n}\n```\n\nVia factory method\n\n```Kotlin\nval layout = HierarchicLayout {\n    layoutOrientation = LEFT_TO_RIGHT\n    automaticEdgeGrouping = true\n    gridSpacing = 20.0\n}\n```\n\n## Quick interface implementation\n\n```Kotlin\nval mode = CreateEdgeInputMode {\n    beginHitTestable = IHitTestable { _, location -\u003e location.x \u003e 0.0 }\n    endHitTestable = IHitTestable { _, location -\u003e location.x \u003c 0.0 }\n}\n```\n\nwill be compiled to\n\n```JavaScript\nconst mode = new CreateEdgeInputMode()\nmode.beginHitTestable = IHitTestable.from((_, location) =\u003e location.x \u003e 0.0)\nmode.endHitTestable = IHitTestable.from((_, location) =\u003e location.x \u003c 0.0)\n```\n\n## Flags\n\nSome yFiles enums are marked as `flags`.\n\n* Use `or` infix method to combine `flags`\n* Use `in` operator to check if `flags` are applied\n\n```Kotlin\nimport yfiles.graph.GraphItemTypes.*\nimport yfiles.input.GraphViewerInputMode\nimport yfiles.lang.contains\nimport yfiles.lang.or\n\nval inputMode = GraphViewerInputMode {\n    clickableItems = NODE or EDGE or LABEL\n}\n\nval nodesAreClickable = NODE in inputMode.clickableItems // true\n```\n\n## Extensions\n\nMost util methods available as extensions only.\n`Graph` and `LayoutGraph` - the most popular receivers.\n\n```Kotlin\nimport yfiles.algorithms.GraphChecker.isAcyclic\nimport yfiles.algorithms.GraphChecker.isCyclic\nimport yfiles.algorithms.Trees.isForest\n\n// ...\n\nval graph: Graph = DefaultLayoutGraph()\n// JS: GraphChecker.isCyclic(graph)\ngraph.isCyclic()\n// JS: GraphChecker.isAcyclic(graph)\ngraph.isAcyclic()\n// JS: Trees.isForest(graph)\ngraph.isForest()\n```\n\n## `for` loop\n\n#### `IEnumerable`\n\n```Kotlin\nimport yfiles.collections.asSequence\nimport yfiles.collections.iterator\n\nval graph: IGraph = DefaultGraph()\n// ...\n\n// iterator() extension allows for loops for IEnumerable\nfor (node in graph.nodes) {\n    println(\"Node layout: ${node.layout}\")\n}\n\n// asSequence() extension\ngraph.nodes\n    .asSequence()\n    .forEach { println(\"Node layout: ${node.layout}\") }\n```\n\n#### `ICursor`\n\n```Kotlin\nimport yfiles.algorithms.asSequence\nimport yfiles.algorithms.iterator\n\nval graph: Graph = DefaultLayoutGraph()\n// ...\n\n// iterator() extension allows for loops for ICursor\nfor (node in graph.getNodeCursor()) {\n    println(\"Node index: ${node.index}\")\n}\n\n// asSequence() extension\ngraph.getNodeCursor()\n    .asSequence()\n    .forEach { println(\"Node index: ${node.index}\") }\n```\n\n## Observable\n\n```Kotlin\nimport yfiles.graph.observable\n\nclass User : Tag {\n    var name: String by observable(\"Frodo\")\n    var age: Int by observable(50)\n}\n```\n\nwill have the same effect as\n\n```JavaScript\nclass User {\n    #name = 'Frodo'\n    #age = 50\n\n    constructor() {\n        makeObservable(this)\n    }\n\n    get name() {\n        return this.#name\n    }\n\n    set name(value) {\n        if (this.#name !== value) {\n            this.#name = value\n            this.firePropertyChanged('name')\n        }\n    }\n\n    get age() {\n        return this.#age\n    }\n\n    set age(value) {\n        if (this.#age !== value) {\n            this.#age = value\n            this.firePropertyChanged('age')\n        }\n    }\n}\n```\n\n##### Details\n\n- [`makeObservable`](https://docs.yworks.com/yfileshtml/#/search/makeObservable)\n- [`firePropertyChanged`](https://docs.yworks.com/yfileshtml/#/dguide/custom-styles_template-styles%23_notifying_of_property_changes)\n\n## `TimeSpan`\n\n```Kotlin\nval c: TimeSpan = 2.hours\nval o: TimeSpan = 0.minutes\nval d: TimeSpan = 1.seconds\nval e: TimeSpan = 3.milliseconds\n```\n\n## Resources Defaults\n\n[What is resources defaults?][41]\n\n```Kotlin\nimport yfiles.lang.ResourceKeys.COPY\nimport yfiles.lang.ResourceKeys.COPY_KEY\nimport yfiles.lang.Resources.invariant\nimport yfiles.lang.get\n\nfun main() {\n    println(invariant[COPY]) // Copy\n    println(invariant[COPY_KEY]) // Action+C;Ctrl+Ins\n}\n```\n\n## KDoc\n\nGenerated!\n\n#### Online Documentation\n\n![Example](assets/online-documentation.gif)\n\n#### Related issues\n\n* [`KT-32815`](https://youtrack.jetbrains.com/issue/KT-32815) - Broken links with double anchor `#`\n* [`IDEA-219818`](https://youtrack.jetbrains.com/issue/IDEA-219818) - Broken links with double anchor `#`\n* [`KT-32640`](https://youtrack.jetbrains.com/issue/KT-32640) - Broken markdown links in `@see` block\n* [`KT-32720`](https://youtrack.jetbrains.com/issue/KT-32720) - `@see` is recommended?\n\n[11]: https://www.yworks.com/products/yfiles-for-html\n\n[12]: http://docs.yworks.com/yfileshtml/\n\n[21]: https://www.yworks.com/products/yfiles-for-html/vsdx-export\n\n[22]: https://docs.yworks.com/vsdx-html/\n\n[31]: https://docs.yworks.com/yfileshtml/#/api/Class\n\n[41]: http://docs.yworks.com/yfileshtml/#/dguide/customizing_concepts_resource-keys#resource_defaults\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturansky%2Fyfiles-kotlin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fturansky%2Fyfiles-kotlin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturansky%2Fyfiles-kotlin/lists"}