Giter Site home page Giter Site logo

newcat / baklavajs Goto Github PK

View Code? Open in Web Editor NEW
1.4K 29.0 105.0 10.73 MB

Graph / node editor in the browser using VueJS

Home Page: http://baklava.tech

License: MIT License

Vue 20.92% TypeScript 70.57% HTML 0.44% CSS 0.16% JavaScript 0.76% SCSS 7.14%
vuejs graph node editor node-editor dataflow dataflow-programming flow-based-programming flow flow-control

baklavajs's Introduction

BaklavaJS

build-status npm

Graph / node editor in the browser using VueJS

Online Demo

example

Package Version
baklavajs npm
@baklavajs/core npm (scoped)
@baklavajs/engine npm (scoped)
@baklavajs/interface-types npm (scoped)
@baklavajs/renderer-vue npm (scoped)
@baklavajs/themes npm (scoped)

Introduction

BaklavaJS is a graph/node editor for the web. It provides an easy-to-use editor together with the ability to create custom nodes. Aditionally, it puts a strong emphasis on extensibility, which leads to a versatile plugin system. To guarantee type safety, the entirety of the BaklavaJS ecosystem is written in TypeScript.

The core functionality is shipped in the @baklavajs/core package. Any other functionality can be added a-la-carte by installing the desired plugins:

  • Engine: Provides functions to run calculations with the graph.
  • Interface Types: Adds types to node interfaces and allowing connections only between types that you want to. It can also automatically convert values from one type to another.
  • Vue Renderer: Displays the editor in the browser using VueJS
  • Themes: A collection of pre-built themes for BaklavaJS

There is also the baklavajs package, which contains the core package as well as all plugins.

Getting Started & Documentation

You can find the documentation here: https://v2.baklava.tech

BaklavaJS v1

The old version of BaklavaJS can be found here: https://github.com/newcat/baklavajs/tree/v1

Sponsors

Top Sponsors

ThePixelDeveloper · Reece Dunham · Adrian Rudnik · Chris Bolton · LittleMouseGames · Andrei Bosco B. Torres · eviltik

Gold Sponsors

Tiger Tang

Sponsors

John Nunley

baklavajs's People

Contributors

a876691666 avatar andreibosco avatar dependabot[bot] avatar felix-engelmann avatar gabrielvidal1 avatar jet132 avatar lukasloeffler avatar mleonowicz avatar newcat avatar opl- avatar ringokam avatar senritsu avatar skadefro avatar starker-xp avatar stevensona avatar stumblinbear avatar tkmnet avatar yojeek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

baklavajs's Issues

Need some help/clarification using this library inside a Vue app

Hi!

I would like to use this library inside a Vue application.

As far as I understand, I need to create custom node types (I used the nodeBuilder for this) and registering them inside the created() Vue lifecycle hook. After that I have an editor instance and I can select my custom node types from the context menu. The engine needs for calculation and it could be automatic. It is ok and clear I think.

But after that, how could I access these calculated results/values outside typscript nodes to access them for later using in my Vue app?
Should I use for this: the engine? subscribing events? or how?

How could I pass some params from the Vue app to my custom nodes? (I want to use my own dynamic values as the rootNode value).

Thanks

IViewNode.position only gets updated after all `addNode` hooks are called

As evident in this line of Editor.vue, the node's positions are only updated once the addNode hooks are called. This however, prevents me from saving the nodetree to an API every time the nodetree updates, such as with:

    this.editor.events.addNode.addListener({}, async (node) => {
      node.events.update.addListener(this, async () => {
        await this.save();
      });
      await this.save();
    });

Is there a workaround for this?

Vue node v-for :key issue when re-loading data?

I've been building some nodes with dynamic interfaces (similar to AdvancedNode in the playground), and when testing the editor.load() behavior to make sure I restore nodes correctly, I noticed some odd behavior with load() that seems like a bug. Apologies if I'm misunderstanding something, as I'm new to both Vue and baklavajs.

Steps to reproduce:

Video: https://www.dropbox.com/s/1nho08p4trd6vdg/baklavajsBugReport.mov?dl=0

  • In the playground, create an AdvancedNode
  • Click Add Input 4 times; see that 4 inputs are created
  • "save" the state - this should generate something like {"nodes":[{"type":"AdvancedNode","id":"node_15859890385070","name":"AdvancedNode","options":[["Add Input",null],["Remove Input",null]],"state":{},"interfaces":[["Input 1",{"id":"ni_15859890416291"}],["Input 2",{"id":"ni_15859890422752"}],["Input 3",{"id":"ni_15859890428753"}],["Input 4",{"id":"ni_15859890466834"}]],"position":{"x":414,"y":128},"width":200,"twoColumn":false}],"connections":[],"panning":{"x":0,"y":0},"scaling":1}
  • click Remove Input and see that Input 4 is removed as expected
  • without reloading the page, "load" the state saved earlier. Input 4 should be restored from the saved state
  • click Remove Input. Expected: Input 4 is removed as before. Actual: Nothing happens visually or in the DOM; however, if you click/drag the node, the component will then update to show the correct inputs

Investigation:

I suspect the issue stems from the fact that nodes (and their corresponding Vue components) are getting torn down and recreated during the load(), and when they're recreated their id is also being restored (as expected, so that their state can be restored as well).

It looks like normally changes to a Node's interfaces trigger updates of the Vue component via the Node's events, which are subscribed to in mounted() (

this.data.events.addInterface.addListener(this, () => this.update());
)

However, when I inspect the Node that was created by the load(), it doesn't have any listeners registered on its addInterface/removeInterface events, unlike the original Node. That seems to match the observed behavior -- changes to the interfaces don't trigger the DOM to update, since there's no listener registered to trigger a forceUpdate, but taking another action like clicking/moving the node modifies some other reactive state and causes Vue to update with the latest data.

I'm not familiar with Vue's caching/reuse strategy, but my hunch is that this behavior could be due to Vue caching the old Node.vue component instance, and then reusing that instance for the new Node. The new Node would have the same .id value that's used as the v-for :key attribute (

). Again, I'm new to Vue, but I'm guessing that in a reuse case like this, the component does not get re-mounted, so the Vue component is actually still registered to the old Node's events rather than the new Node's events?

If my assumptions are correct, then it seems like one potential fix would be to change the :key value so it's a truly unique id per Node instance, rather than the .id which gets restored when a Node is load()ed from saved state.

Hopefully this makes sense and is helpful! And thanks so much for building this project, I've really enjoyed working with it so far!

Suggestion: Node category CSS

It may be useful to include a CSS class named node-<category > in the parent node div, so that similar nodes can be styled differently. For example: render math nodes with a blue title, smaller in width, or no border radius at all.

How to set the value of text input?

export default class PrintNode extends Node {
    constructor() {
        super();
        this.type = "PrintNode";
        this.name = this.type;
        this.addInputInterface("Value");
        this.addOption("input_field","InputOption");
        this.addOption("Text_field", "TextOption", "empty");
    }
    load(state) {
        super.load(state);
    }
    calculate() {
        let asd = "Nothing";
        **this.getOptionValue("Text_field") = asd;**
        console.log(asd);
    }
}

So I am trying to pass a string from one Node to this Print node. And I just noticed that I can really jus pass string to text_field option value to change it. Could you help me?

I kinda went around this problem and used InputOption and then used setOptionValue.

Also could you please provide any examples on how to save all nodes and then load them? There are not much information in documentation (examples)

How to use editor.load()?

I can't find anything useful about this in the docs. Right now I have this code called on button click (data is string):
editor.load(data);
but it causes
Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator)).
Thanks for help!

Mismatch between Node.addOption and NodeBuilder.addOption

Node.addOption has a default parameter defaultValue that defaults to null, but NodeBuilder.addOption has an optional parameter defaultValue which therefore is undefined if not set. However, you can't set null as the defaultValue with a NodeBuilder (to match the Node behavior) because it checks typeof the value and throws because typeof(null) is "object".

Not a major issue, but it did catch me off-guard

how to create a node programatically

I'm working on an app and i need to have two nodes (a start and an end) on application load.

is there a way to add a node programatically?, i'm kinda confused with the documentation. should i save the whole state and load it on application start?.

i found this method addNode but i cant seem to find which parameters receives to add the node.

could you please provide an example?

Possible to make "object nodes" and get reference?

Ok, I have an educational project where I need to create a bot using a nonSQL DB (firebase, mongodb etc).
I'll try my best to explain what I'm trying to do:

So, I have a chat bot, where it's structure is object oriented, where the object names matters, and each object is composed by,
A Text and it's next steps.
All object steps are structured the same way.

example of S Objects (S is just a prefix for the object name):

s0: {
      text: "Hello and welcome to botchat."
      nextStep: {
                      "1": { description: "show Website link", target: "s1"}
                      "2": { description: "end chat", target: ""}
                      }
}
s1: {
      text: "some website here."
      nextStep: {}
}

I have a backend to treat it, so don't really mind so much how it works,
So, what I am trying to do is create a Node where it acts like these S Objects.

Is it possible make the bot flow using baklavajs? is Yes, how hard will it be?

P.S. I'm coding with Angular 9 framework

BaklavaJS 1.5.2 Build Error

I just updated BaklavaJS to the latest version and now nothing builds. I think something is wrong with the build/dependency configuration, especially with regards to @baklavajs/events. A reproducer that shows the same error has been attached. repro.zip

This is my package.json.

{
  "name": "vision_frontend_vue",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "profile": "vue-cli-service build --report"
  },
  "dependencies": {
    "@baklavajs/core": "~1.5.2",
    "@baklavajs/plugin-interface-types": "~1.5.2",
    "@baklavajs/plugin-renderer-vue": "~1.5.2",
    "core-js": "^3.6.4",
    "vue": "^2.6.11",
    "vue-class-component": "^7.2.3",
    "vue-property-decorator": "^8.4.1",
    "vue-router": "^3.1.6",
    "vuetify": "^2.2.21"
  },
  "devDependencies": {
    "@mdi/font": "^5.0.45",
    "@vue/cli": "^4.3.1",
    "@vue/cli-plugin-babel": "^4.3.1",
    "@vue/cli-plugin-typescript": "^4.3.1",
    "@vue/cli-service": "^4.3.1",
    "sass": "^1.26.3",
    "sass-loader": "^8.0.2",
    "typescript": "^3.8.3",
    "vue-cli-plugin-vuetify": "^2.0.5",
    "vue-template-compiler": "^2.6.11",
    "vuetify-loader": "^1.4.3"
  }
}

repro.zip

Error Message:

> [email protected] build /home/steven/vision_frontend_vue
> vue-cli-service build


Starting type checking and linting service...
Using 1 worker with 2048MB memory limit
 ERROR  Failed to compile with 10 errors4:59:52 PM

 error  in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/connection.d.ts

ERROR in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/connection.d.ts(2,30):
2:30 Cannot find module '@baklavajs/events'.
    1 | import { NodeInterface } from "./nodeInterface";
  > 2 | import { BaklavaEvent } from "@baklavajs/events";
      |                              ^
    3 | import { IConnection, ITransferConnection } from "../types/connection";
    4 | export declare class Connection implements ITransferConnection {
    5 |     id: string;

 error  in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/editor.d.ts

ERROR in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/editor.d.ts(5,71):
5:71 Cannot find module '@baklavajs/events'.
    3 | import { Connection, DummyConnection } from "./connection";
    4 | import { IState } from "../types/state";
  > 5 | import { PreventableBaklavaEvent, BaklavaEvent, SequentialHook } from "@baklavajs/events";
      |                                                                       ^
    6 | import { IEditor, IPlugin, IConnection, NodeConstructor, INode, IAddConnectionEventData, IAddNodeTypeEventData } from "../types";
    7 | /** The main model class for BaklavaJS */
    8 | export declare class Editor implements IEditor {

 error  in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/node.d.ts

ERROR in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/node.d.ts(4,71):
4:71 Cannot find module '@baklavajs/events'.
    2 | import { INodeState } from "../types/state";
    3 | import { Editor } from "./editor";
  > 4 | import { PreventableBaklavaEvent, BaklavaEvent, SequentialHook } from "@baklavajs/events";
      |                                                                       ^
    5 | import { NodeOption } from "./nodeOption";
    6 | import { INode, IAddInterfaceEventData, IAddOptionEventData, IOptionEventData, INodeUpdateEventData } from "../types";
    7 | export interface IInterfaceCreateOptions {

 error  in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/nodeInterface.d.ts

ERROR in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/nodeInterface.d.ts(2,71):
2:71 Cannot find module '@baklavajs/events'.
    1 | import { IInterfaceState } from "../types/state";
  > 2 | import { BaklavaEvent, PreventableBaklavaEvent, SequentialHook } from "@baklavajs/events";
      |                                                                       ^
    3 | import { INodeInterface, INode } from "../types";
    4 | export declare class NodeInterface implements INodeInterface {
    5 |     id: string;

 error  in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/nodeOption.d.ts

ERROR in /home/steven/vision_frontend_vue/node_modules/@baklavajs/core/dist/baklavajs-core/src/nodeOption.d.ts(2,55):
2:55 Cannot find module '@baklavajs/events'.
    1 | import { INodeOption } from "../types/nodeOption";
  > 2 | import { PreventableBaklavaEvent, BaklavaEvent } from "@baklavajs/events";
      |                                                       ^
    3 | export declare class NodeOption implements INodeOption {
    4 |     /** Name of the component that should be displayed for the option */
    5 |     optionComponent: string;

 error  in /home/steven/vision_frontend_vue/node_modules/@baklavajs/plugin-renderer-vue/dist/baklavajs-plugin-renderer-vue/src/viewPlugin.d.ts

ERROR in /home/steven/vision_frontend_vue/node_modules/@baklavajs/plugin-renderer-vue/dist/baklavajs-plugin-renderer-vue/src/viewPlugin.d.ts(3,32):
3:32 Cannot find module '@baklavajs/events'.
    1 | import { VueConstructor } from "vue";
    2 | import { IPlugin, IEditor } from "../../baklavajs-core/types";
  > 3 | import { SequentialHook } from "@baklavajs/events";
      |                                ^
    4 | import { IViewPlugin } from "../types";
    5 | import NodeView from "./components/node/Node.vue";
    6 | import NodeOptionView from "./components/node/NodeOption.vue";

 error  in /home/steven/vision_frontend_vue/src/options/CheckboxOption.vue

ERROR in /home/steven/vision_frontend_vue/src/options/CheckboxOption.vue(16,29):
16:29 Cannot find module '@baklavajs/core/dist/types'.
    14 | <script lang="ts">
    15 | import { Component, Vue, Prop } from "vue-property-decorator";
  > 16 | import { INodeOption } from "@baklavajs/core/dist/types";
       |                             ^
    17 | 
    18 | @Component
    19 | export default class NumberOption extends Vue {

 error  in /home/steven/vision_frontend_vue/src/options/NumberOption.vue

ERROR in /home/steven/vision_frontend_vue/src/options/NumberOption.vue(37,29):
37:29 Cannot find module '@baklavajs/core/dist/types'.
    35 | <script lang="ts">
    36 | import { Component, Vue, Prop } from "vue-property-decorator";
  > 37 | import { INodeOption } from "@baklavajs/core/dist/types";
       |                             ^
    38 | 
    39 | @Component
    40 | export default class NumberOption extends Vue {

 error  in /home/steven/vision_frontend_vue/src/options/RangeOption.vue

ERROR in /home/steven/vision_frontend_vue/src/options/RangeOption.vue(49,29):
49:29 Cannot find module '@baklavajs/core/dist/types'.
    47 | <script lang="ts">
    48 | import { Component, Vue, Prop } from "vue-property-decorator";
  > 49 | import { INodeOption } from "@baklavajs/core/dist/types";
       |                             ^
    50 | 
    51 | @Component
    52 | export default class NumberOption extends Vue {

 error  in /home/steven/vision_frontend_vue/src/options/TextOption.vue

ERROR in /home/steven/vision_frontend_vue/src/options/TextOption.vue(18,29):
18:29 Cannot find module '@baklavajs/core/dist/types'.
    16 | <script lang="ts">
    17 | import { Component, Vue, Prop } from "vue-property-decorator";
  > 18 | import { INodeOption } from "@baklavajs/core/dist/types";
       |                             ^
    19 | 
    20 | @Component
    21 | export default class TextOption extends Vue {

Suggestion: Add class to ports

In order to allow better styling for ports, perhaps add a style to it depending on their type. For example: adding the "string" type to a port will add the CSS class "__port-string." This would allow, for example, square or triangle ports for ease of recognition in extra special port types.

Can't set node names using NodeBuilder

The current NodeBuilder API reuses a single argument for both the node type and name. This makes it unnecessarily difficult to set a more user friendly display name for the node. It also completely removes the ability to translate names of nodes created with NodeBuilder.

Firefox: Zoom is very slow

Apparently, Firefox has a different deltaY value per mouse wheel event. Currently, the deltaY value is divided by a constant of 3000 in the Editor.vue. This probably needs to be changed for Firefox.

Suggestion: inline input/output

Not exactly an issue, but a feature request. I'm using this library in an attempt to build a sort of visual programmer for my quest system, however the lack of a way to make a nice looking "execution input/output" is a bit annoying.

Current:
image

Suggestion:
image

I'm hoping this is something that you'll consider adding, as this is the only library that I can get to reliably work within VueJS. Thanks in advance! ^^

If not, if you could perhaps point me in the right direction to the location in which I can add the feature myself, that would be great!

Also, if you could also consider having an option to move the options below the inputs and outputs, that would also be great!

need a sample example without vuejs

It look like a perfect editor node. But the documentation still very hard to follow . Can you put a simple example code to help us understand the basic for the library.
Thanks

Sidebar in native usage

When using BaklavaJS in a native js environment is it still possible to use the sidebar?
Is there any way I can emulate a Vue component to register as an option?

Thoughts on aborting and/or restarting calculations?

(this is less of an issue and more of a discussion question around the Engine, apologies it's a bit long)

I've been wondering if the Engine can/should be changed to abort and/or restart a calculation if a new one is requested while a previous one is in progress. I ended up running into a small issue with the Engine's calculateOnChange behavior due to some event ordering triggering an onChange(false) immediately before an onChange(true), in which case the onChange(true) essentially gets dropped (and the node ordering does not get recalculated) because the calculation started by the onChange(false) was still in progress. I was able to work around that by making some of my code asynchronous to ensure the onChange(true) fires before the onChange(false) (see https://github.com/skipscooters/mapgraphs/blob/e4795f877b250f5facb4ffc1fb92a1a58226a12d/app/src/nodes/DynamicInputsNodeBase.ts#L42 for the actual implementation if you're curious), but that's what initially prompted my thinking about how concurrent calculation requests are/should be handled by an Engine.

The second related concern I ran into was with calculations that take a while. Since calculate is async, it's easy to have instances where the user is changing the graph while a calculation is in progress, and right now that doesn't play too well with calculateOnChange (since a change during a calculation doesn't trigger a new calculation, it's just dropped).

So one idea I had would be to make the Engine restart a new calculation once the first one completes if a change occurred during that calculation (and potentially looping repeatedly if there continue to be changes during the restarted calculations). Then a potential improvement on top of that could be to allow calculations to be aborted, so that if the graph is changed during a calculation the Engine doesn't need to finish calculating all the nodes before starting a new calculation (this has some potential issues if node calculations aren't pure functions, but there are always going to be potential race conditions as long as graph changes are allowed to happen concurrently with calculations, so the calculations kind of need to be pure functions regardless).

One other topic I was also thinking about was the fact that Engine.calculate doesn't have any mutual exclusion (except for internal onChange-triggered calculations), which could be problematic if multiple long-running calculations are triggered concurrently with different data, since the intermediate calculation results are stored on the shared graph (nodes and interface values) during a calculation. You could imagine a case where a node's calculate method is async and takes a nondeterministic amount of time (e.g. making a network request), which could result in a second concurrent calculate() actually "passing" the first as it makes its way through the graph, resulting in potentially inconsistent/corrupt data throughout the graph. I don't really see a good way to prevent this other than mutual exclusion, unless each calculation operated on a cloned graph or something.

I'm happy to jump in and try making some of these changes to see how they work out, but wanted to check if you already had any thoughts on the topic first.

Access node state in node option??

Is there a way to access Node state within option?

Great library! But documentation is kinda sparse. I would love to contribute to the doc after I gain a better understanding of the library 🙇‍♂️

Choose side of inputs/outputs

Is it possible to set which side will be used for output or input?
I would like to have outputs and inputs positioned on the same side for some of my nodes.
Thanks.

Add contributing guide

Setting up the environment to contribute to this project has proven itself more challenging than I anticipated. It would be useful to include a guide for new contributors to make their lives easier.

After some experimentation I came up with these commands, though I didn't end up setting up a webpack watcher to automatically rebuild the projects on changes. From my digging it doesn't seem this repo includes a quick way of doing that.

# Install Lerna (https://lerna.js.org/)
npm install -g lerna
# Download and setup the repo
git clone [email protected]:newcat/baklavajs.git
cd baklavajs
lerna bootstrap --npm-client=npm
# Build all the packages
lerna run build
# Run the playground (with npm)
cd packages/baklavajs-playground
npm run serve
# Run the playground (with yarn, from project's root directory)
yarn run playground

Suggestion: style bezier connection

In the event a connection port is styled a different color, it would be very useful to be able to make a distinction between connection lines by styling the line the same color as the ports they connect between.

Serious lag with >30 nodes

I can only imagine VueJS is attempting to redraw the entire scene when moving a node around, because serious lag starts to occur on my machine at around 30 nodes. Only the node in question and the connections on it should be moved/redrawn, however I'm pretty sure the entire graph is.

Mobile devices friendly

Hi, @newcat thank you for your work. Any plans to make Baklava.js working on mobile devices?
Currently it does not pan. Nodes dragging does not work also...

[Bug] Node.addOption after constructor does not work

When you create a node with a class (like here) and you call this.addOption(...) not in the constructor but afterward, no option visible gets added. The data still changes but the view doesn't display the new option.

Core Version: 1.5.4
Options Version: 1.5.4
Renderer Version: 1.6.0

Thumbnail and minimap support?

Hi @newcat What you have done is really awesome! I am using it with Vuetify for a new project. Is there a way to create a thumbnail with current node editor? So that the diagram could be selected by the thumbnail. Also, is it possible to have minimap support? It's really useful for navigating when there're many nodes in the editor.
Thanks!

Blur event isn't called

Hi, blur event on html elements isn't called when I start dragging baklavajs nodes. Any ideas how to fix this?

Long context menus go off screen

In the event that the context menu has many many items, it can regularly go off screen. Perhaps bump the menu up when it's displayed, and if it's excessively long, make a scroll bar?

baklavajs for data model UI

Hi, thanks for your outstanding work. I would like to try to use baklavajs for data model editor. Where use has something alike tables and can create relations in between.
Question. Is that possible to make connection clickable? I would like to display a dialog with connection options.

Any suggestions maybe how to use baklavajs for such purposes as mine?

Thanks.

Vuejs Electron js with vuetify not working

I have a simple app with electron js make with vue cli and followed your guide, but the editor is not getting rendered properly, is there any additional configuration missing.
baklavajs

Electron sample

Hi

Can anybody provide me with an example of how it could/should work together with Electron? I really have no idea how it's supposed to work together

Thanks

Min and max for NumericOptions?

Is there an easy way to inject the min and max of a number into a custom option? I don't see such a thing being possible currently.

Suggestion: context menu styling

Perhaps include category-<id> and item-<node type> CSS classes in context menus, so, for example, list items can inherit the color of the node itself. I'd make a PR, but it seems the context menu doesn't get passed any node data, so I'll leave that decision up to you.

Also, hide the divider if no categories or no default nodes exist

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.