Coder Social home page Coder Social logo

papyrus-gefx's Introduction

Papyrus GEFx Integration

The focus of this project is to integrate a GEFx Editor (Currently based on the GEF 5.x branch, available in Eclipse/Photon) with GMF Runtime and Papyrus

The idea is to provide an editor based on GEFx and JavaFX, while retaining the compatibility with existing Papyrus models (Semantic + Notation, CSS, Properties View, Model Explorer, GMF Genmodel...)

Dependencies

The project depends on Eclipse 2019-03 & Java 11, GEFx (Currently, 5.0.2 / 2019-03), Papyrus 4.x (Currently, [4.0.0, 4.3.0], any version between Photon.0 and 2019-03) and E(fx)clipse (3.5.0, not available from the Eclipse release train anymore)

Project status

This project is still work-in-progress, and some parts of the code have been implemented a long time ago, while GEFx APIs were still moving a lot. Thus, these parts of the code may be disabled (Typically commented out) or broken, although most of them have now been properly migrated.

When everything is setup properly, you may open a Class, Component or Composite Diagram from an existing Papyrus Model, via the Model Explorer: Right click > Open With > Diagram Editor (GEF4). If the Diagram only contains supported elements, here's what it might look like:

GEF Legacy vs GEFx-GMF

Side-by-Side in the same Papyrus Editor: GEF Legacy (Left), GEFx (Right)

Supported Diagrams & Elements

The editor is able to render the following elements:

  • Nodes (Including Border Items)
  • Compartments (Structure or List)
  • Labels
  • Connectors
  • Palettes

A few Papyrus Diagrams are currently supported: Class, Composite, Component, State Machines and Activities. However, support isn't complete, as some of the features used by the standard Papyrus/GMF implementation aren't available in GEFx yet.

Basic interactions are supported, including:

  • Select/Multiselect/Deselect
  • Move (But not reparent)
  • Resize
  • Creation of (Most) Nodes and List Items
  • Creation of (Most) Edges
  • Collapse/Expand compartment To be restored

How to install

There is no official release for this project yet. Some integration builds are triggered on Papyrus' Jenkins instance. You can install the Papyrus-GEFx Connector from this update site: https://ci.eclipse.org/papyrus/job/Papyrus-GEFx-Integration/lastSuccessfulBuild/artifact/repository/

Note that you will need Eclipse 2019-03 running on Java 11. If you want to use the Papyrus GEFx Diagrams inside of the Papyrus Editor, you need to explicitly install the Papyrus Feature ("Papyrus for UML") from http://download.eclipse.org/releases/2019-03

papyrus-gefx's People

Contributors

camilleletavernier avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

papyrus-gefx's Issues

[Interactions] Multi-selection policies do not ensure that all selected elements are valid

When dragging multiple selected elements, the event is delegated to each individual selected element. That works fine when all selected elements are similar (e.g. all nodes), but causes exceptions when selecting e.g. Nodes + Edges. In that case, the current code tries to move the edges as if they were nodes, which causes exceptions:

java.lang.NullPointerException
	at org.eclipse.papyrus.gef4.gmf.editor.handlers.MoveNodeHandler$1.doExecuteWithResult(MoveNodeHandler.java:80)
	at org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand.doExecute(AbstractTransactionalCommand.java:247)
	at org.eclipse.emf.workspace.AbstractEMFOperation.execute(AbstractEMFOperation.java:150)
	[...]

[Renderer] Add styling for Name Label

Papyrus CSS support a background color for the main label of a Node (Typically name) that may be different from the Node's background color. GEFx should support this CSS property

[Renderer] Improve ImageService to support e.g. Overlays

This is a follow-up on #11

While we now have an ImageService that can use participants, it is limited to Images that can be identified by a String URL. This means it can't dynamically create new images, e.g. to support Visibility overlays.

A simple way to support overlays would be to let the ImageService add new Image instances to the ImageRegistry, with a custom key/url (e.g. a WritableImage created by stacking several existing images). This would only require an additional method in the ImageRegistry, without breaking any API, and keeping the ImageService API very simple.

We could also consider supporting more complex UI Nodes rather than just images; but that would probably require deeper changes to the ImageService.

At the very least, we want to be able to support overlays; with at least two use cases:

  • Visibility overlays for UML NamedElements (e.g. Property/Operation)
  • Validation marker overlays (Error/Warning displayed on top of the Element Icon)

[Renderer] Support Papyrus custom palettes

Currently, Papyrus palette models are directly referenced from the DI Module for each diagram (Class, Activity...)

This doesn't provide any support for customized Papyrus palettes, used in DSMLs or custom UML cases. The palettes should be read from the Papyrus architecture definition when possible

[Renderer] Anchors are not always properly refreshed

When opening the diagram, the anchor are incorrectly positioned. They get to the right position after moving the element around (And stick to it after that).

There is probably a missing refresh on startup, during the initial display.

The issue may be specific to Packages (Because the Shape also suffers from refresh issues on startup, which might cause a layout delta), or it may be more general for any contained anchorage node.

When opening the model initially: (Left: expected, right: buggy behavior)
packageanchorshift

After moving the package, everything comes back to normal:
packagesshift-afterrefresh

[Interactions] Fix / Implement the base interaction policies

This should include, at least:

  • Select ✔️
  • Move ✔️
  • Resize ✔️
  • Collapse/Expand compartments
  • Bend connections
  • Retarget connections

This set of interactions will be useful to demonstrate how to properly use/bind Handles and Feedback parts. Move/Resize should also work with multi-selection, which should demonstrate the Handler-to-Policy delegation.

[Renderer] Add/Fix decorations for links

Currently, we use CSS to add static link decorations. However, when dynamic decorations are required, CSS is not enough (e.g. to distinguish Source/Target navigability or composition for an Association). We need to support this programmatically (And maybe consider some CSS extensions later on, although specifying multiple edge decorations with CSS would be tricky)

[Renderer] Investigate the use of Anchors for BorderItems

Initially, BorderItems have been implemented with a custom Locator API: if a Locator was present, it was responsible for applying a custom layout to the Node; otherwise the Layout was delegated to the parent figure (Typically, List or Structure Compartment)

The Locator concept is redundant with the standard GEFx Anchorage/Anchored relationship, which should be used instead.

Commit 4719c66 already started this (The Locator has been deprecated, and the Anchorage management has been moved up to the BaseContentPart, instead of ConnectionContentPart). This should be continued to support at least Ports in Composite/Component, and Template in Class Diagram.

[Interactions] Support keybindings / keyboard handlers

Currently, we only support interactions through mouse-policies. We should support keyboard interactions, with at least two mechanisms:

  • GEF Key Handlers (IOnStrokeHandler), for Diagram interactions (Or modifiers, to be used with Mouse Interactions)
  • Eclipse Key Bindings, for standard Command/Handler interactions (e.g. Deleting an element)

In most cases, we want Eclipse Key Bindings, as they can be integrated with Menus or Toolbars as well; but we should provide examples for both cases.

In Diagrams, I think Papyrus only uses Keyboard as Mouse-interaction modifiers (All keybindings are delegated to the Eclipse Commands framework).

[Interactions] Fix Marquee Selection: Diagram Content Part shouldn't be included in the selection

Our custom MarqueeOnDragHandler extends the GEF one (org.eclipse.gef.mvc.fx.handlers.MarqueeOnDragHandler), but is not 100% compatible with it. Especially, we don't support empty selection in Papyrus (We always select the diagram content part if there is no other selection). However, GEF's MarqueeOnDragHandler (And especially SelectionOperation) always prepends the selection to whatever is already selected (i.e. at least the diagram part in our case).

As a result, when we use Marquee Selection, we always get the selected parts + the diagram content part (Instead of just the selected parts, or the diagram content parts if nothing is touched by the marquee selection area)

To reproduce:

  • Use marquee selection on any node(s)
  • Check the properties view: the covered node(s) is selected, as well as the diagram content part

Expected behavior:

  • Only the parts inside the marquee selection area are selected (Excluding the diagram content part)
  • If (and only if) the marquee selection area is empty, only the diagram content part is selected

Embed this project to my application

Hi,

I want to develop a java program which allow me to draw class diagram like Papyrus, i want to embed this project to my application if possible.

Can you help me please how to embed it?

Thank you

[Renderer] Add support for connection Decorations

The support for Connection Decorations should be improved. This includes:

  • Adding UML-specific CSS properties to identify the required semantic attributes (e.g. Directed Association, Composite Association...)
  • Adding the missing decorations to the existing DecorationFactory
  • Adding support for customization (Line attributes, e.g. Color, Width)
  • Support decorations on the lines (e.g. GeneralOrdering)
  • Support multiple/composite decorations (e.g. "Navigable composite owned by classifier") (Note: they must not be stacked on top of each other, but follow each other)
  • Bonus step: Improve clipping of the Connection Line below the Decoration. Currently, zooming on an Arrow connection end doesn't show a perfect triangle, because the 1px-wide connection line below it looks like a rectangle when zoomed in:

image

[Tests] Add JavaFX unit tests

Now that #6 is complete, we should be able to provide true unit-tests for individual parts and visuals

The plan was to use TestFX for this; however it is currently not possible due to Releng limitations.

E(fx)clipse dynamically makes JavaFX available on the Module Path via JavaFX Jars shipped through a P2 Repository, which allows to use JavaFX in a very transparent manner for the end-user (He doesn't need to mess with his VM's Modules manually)

However, the OSGi version of TestFX uses some package-imports to javafx packages, which can only be resolved by OSGi if these modules are actually available on the module path. The problem is that this isn't compatible with E(fx)'s approach, making it impossible to install TestFX (e.g. via P2).

A solution might be to require having OpenJFX available at build time, and adding it explicitly on the Module Path (As expected by OSGi and TestFX). This is less flexible that E(fx)'s dynamic approach, but it would only be a requirement for developers and build servers. However, I've not tried this approach yet and I don't know if it would actually work

[Renderer] Fix the Anchor projection

Currently, we use a fixed location for all anchors, even when the link intersects a different border. In GMF, the real anchor is computed at the first intersection point between the link and the target anchor:

anchorsissue 7

(Expected behavior, on the left; buggy behavior, on the right)

[Interactions] Support Context Menus in Diagrams

We currently can't open a context menu in a GEFx Diagram. We should implement this.

There are a few options for this:

  • Use the Eclipse Context Menus (Via the Eclipse Menu Service), and open an SWT Menu on top of the Diagram. This would be the simplest solution
  • Use the Eclipse Menu Service with a custom (JavaFX) menu. This would be more portable. However, JavaFX Context Menus in an FXCanvas don't work on Linux (Plain JavaFX Context Menus work fine, and FX-in-SWT ContextMenus work fine on other platforms as well)

We could also go for a complete custom approach, or hide the Eclipse Menu Service behind our own API to allow deployment outside of Eclipse (But in general we want to reuse the Eclipse capabilities for defining menus, so we'll probably still rely on the Eclipse Menu Service)

[Releng] Fix the tests & restore the Maven build

During the extraction of a project to a separate repository, some parts of the build have been lost. The refactoring also caused some tests failures (Including compile errors).

The goal of this issue is to fully restore the Maven/Tycho build, including static analysis & tests.

[Architecture] Fix/Improve Feedback and Handle parts

The current Feedback and Handles factories were developed on the GEF4 0.3 architecture and have not been updated since (Or barely, just to ensure it still compiles/works)

They must be refactored to match the GEF 5.x architecture

[Renderer] Improve Shapes rendering

Currently, we use JavaFX Shapes (Via Region#setShape) to render special nodes, such as Packages or Comments.

However, Shapes work fine when there is an external border, or when segments don't overlap each other. For Package and Comment, this isn't the case, and using a Path or a Polyline will give the same incorrect result: JavaFX will try to close the shape by itself to draw the gradient inside it, which will typically result in double-width borders where the closing happens.

I'm not sure what's the best way to draw these figures in JavaFX, while still keeping the easy Background/Border customization capabilities.

For now, I've taken some shortcuts, by only drawing the outer border of these shapes:

shapesborders

(On the left, what we have now; on the right, what we want)

When trying to draw the entire border, we can see that it creates a double border (Even if the Path doesn't specify it):

invaliddoublebordershape

The comment tried to overcome this issue by drawing a triangle in the top-right corner, on top of the base shape, but I had to remove it because of Issue #12. It might still be a way to make it work (Overlaying the missing pieces), but we need to be careful about the lifecycle of the figures and parts. Another approach could be to investigate the Border customization capabilities of JavaFX; although the Javadoc seems to indicate that this wouldn't work in our custom-shape scenario:

When applied to a Region with a defined shape, the border width and stroking information for the top is used, while the other attributes are ignored.

For the Package, another alternative would be to style the Label separately from the Package body/compartment (Use a Left/Top/Right border for the label tab, and a full border around the Package body). However, this might make it difficult to have a clean gradient that covers both the Label and Body, as we have today.

[Renderer] Improve Locators

Currently, the Locator API is very simple, and is sufficient for delegating the layout of any floating element (Border Item, Floating Label attached to a Node, Floating Label attached to a Connection...)

However, it doesn't allow for proper feedback, because we can't anticipate how the Locator will treat its constraint (Relative to the host's top-left point? To the Connection's middle point? To the Connection's Top-left point?)

We should improve the API to at least support converting from a "proposed rectangle constraint" to a "valid rectangle constraint".

To get more flexibility, the Locator should also be able to configure/expose its "reference point", i.e. the point that corresponds to the X/Y Position (For a Port, it may be the Top-Left point, or the Center point).

We may need a similar reference point on the Anchorage side (Some Connection Labels are placed relative to the middle point of the connection; some are relative to the start or end point of the connection).

By supporting both cases (Reference Point on the Anchored, and Reference Point on the Anchorage), we should support the following combinations:

  • Connection Label left-aligned over the start point of its connection
  • Connection Label right-aligned over the end point of its connection
  • Connection Label centered over the middle point of its connection
  • Port placed on it's parent's border (Either from the top-left corner, or from the center of the port)
  • ...

Exposing these values directly in the API may also help with providing adequate feedback.

[Renderer] Add custom layouts/containers for Regions

Regions in a StateMachine Diagram can be freely arranged within a single StateMachine or Composite State. We should provide a custom Figure/Container to handle this.

The Regions container should have the same capabilities as in Papyrus, i.e. a set of nested Split Panes, which can be either Vertical or Horizontal:

statemachineregions

[Views] Add Outline support

Papyrus/GMF provides an Outline view, which displays the entire diagram in a small view, along with the current editor viewport area. This is useful to quickly navigate large diagrams, and get a general overview:

image

This would be especially useful in GEFx, since the canvas has an infinite size, where it can be difficult to find elements that have been added far away from the center.

However, we must be careful about performances: the Papyrus/GMF Outline view introduces some severe performance issues when the viewport size changes (It needs to redraw the entire outline image, which can be very slow). On the other hand, incremental outline updates work fine on Papyrus/GMF.

Update to the 2018-09 release

Eclipse 2018-09 has been released a few weeks ago; the target platforms should be updated.

It doesn't introduce any breaking change (GEF and E(fx)clipse have not been updated, and Papyrus only contributed a minor version update)

[Releng] Provide public update site

Currently, there is no way to consume Papyrus-GEFx, beside cloning the repository & building the project locally

The Papyrus GEFx artifacts should be published, either to download.eclipse.org, or maybe to the market place

[Dependency Injection] Support AdapterMaps overrides

In #13, we added factory-based injection with priorities, to support injection of different types for different parts. This allows us to provide generic services for generic parts, and specific services for specific parts, when the generic behavior is not sufficient.

This approach works well for 1-1 injection, where the ContentPart knows exactly which service(s) it needs. However, interactions are based on adapters, and the Part doesn't need to know which adapters will be present at runtime; so we can't use the same approach (at least not directly).

We should find a solution similar to #13, but for interactions/adapters. For example, we want to provide a generic GMF implementation of the MoveNodeHandler, but still be able to override it for some specific content parts (e.g. for a PortContentPart with a custom Locator). However, AdapterMaps injection doesn't support conflicts/overrides; so we'll need a factory-based approach.

[Renderer / Interactions] Properly distinguish between IRootPart and DiagramContentPart

Currently, we have a IRootPart (that doesn't have a Content), and a DIagramContentPart (That is a IContentPart representing the GMF Diagram, i.e. the root)

Since the DiagramContentPart doesn't have any visible geometry (It's a Pane with pickOnBounds=false), all events/policies/handlers are passed to the IRootPart (e.g. creation of nodes on the diagram surface is handled by IRootPart policies). The DiagramContentPart should be the one handling all root interactions (Creation, selection...).

Currently, because the IRootPart handles everything, we need some tests like this in the code:

assert target instanceof IContentPart || target instanceof IRootPart : "CreationFeedback can only be installed on IContentParts or IRootPart";

which should be simplified, so that the diagram surface (root) behaves like every other content part

[Renderer - Interactions] NPE when selecting a Comment/Constraint node

The following NPE is thrown when trying to select a Comment or Constraint node:

java.lang.NullPointerException at org.eclipse.gef.mvc.fx.parts.AbstractFeedbackPart.doDetachFromAnchorageVisual(AbstractFeedbackPart.java:116) at org.eclipse.gef.mvc.fx.parts.AbstractVisualPart.detachFromAnchorage(AbstractVisualPart.java:377) at org.eclipse.gef.mvc.fx.parts.AbstractVisualPart.detachFromAnchorage(AbstractVisualPart.java:355) at org.eclipse.gef.mvc.fx.behaviors.AbstractBehavior.removeAnchoreds(AbstractBehavior.java:563) at org.eclipse.gef.mvc.fx.behaviors.AbstractBehavior.removeFeedback(AbstractBehavior.java:636) at org.eclipse.gef.mvc.fx.behaviors.AbstractBehavior.removeFeedback(AbstractBehavior.java:587) at org.eclipse.gef.mvc.fx.behaviors.AbstractBehavior.removeFeedback(AbstractBehavior.java:603) at org.eclipse.gef.mvc.fx.behaviors.SelectionBehavior.removeFeedbackAndHandles(SelectionBehavior.java:146) at org.eclipse.gef.mvc.fx.behaviors.SelectionBehavior$1.onChanged(SelectionBehavior.java:60) at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)

To be investigated...

[Renderer] Properly handle Text & Images

Currently, the Images are hard-coded in the generated code (By the NamedElement*ContentPart, which are explicitly referenced by the Code Generator, making it dependent on UML), and Labels are provided via a TextAdapter (Service), which delegates to GMF. However, the parsers are not always valid, and may return a text (In theory, they should return the same text as Papyrus Diagrams).

Investigate why this happens & clean this up. At the end:

  • Icons should be correct ✔️
  • Texts should be correct ✔️
  • The generated code & code generator shouldn't depend on Papyrus and/or UML (They may depend on GMF and Notation) ✔️

[Renderer] Improve layout consistency when using shapes

This issue has found while working on #16 and will mostly affect cases where the shape is changed dynamically (Which isn't the typical case - in standard UML the shape is related to the type of semantic element, e.g. Package or Comment, and will never change after created).

When using a standard Region, the border will affect the layout (Border width is involved in inner size computation). However, when using Region#setShape, the Border is applied to the visual shape, but is no longer taken into account for layouts. The result is especially visible when we increase border sizes:

image

On packages in the left column (Package Shape), the border doesn't affect the position of the label, which is then hidden under the border. In the right column (No Shape), the border affects the position of the label, which remains readable in all circumstances (Making the package bigger when necessary).

This layout inconsistency causes the Package to jump around when switching from the Package Shape to the Rectangle shape (The bigger the border, the worse it becomes)

I'm not sure yet what the best solution would be; but we definitely want consistent results

Package also highlights the "worst case scenario" in that it will need twice as much vertical space for its borders in its Package Path form (Above and Below the tab) compared to its square form, but other simpler shapes are also affected by the layout inconsistency. For example, comments:

image

[Viewer] Investigate asynchronous loading of the editor

Unlike SWT, JavaFX supports creating a Node tree outside of the UI Thread. FX Thread is only required when manipulating nodes that already belong to a Scene.

It should be possible to load a diagram in a background thread (While presenting a progress bar in the UI thread), and only attach the diagram to the scene once it's been initialized (i.e. When the initial content part hierarchy has been built). This way, only the initial rendering would freeze the UI, which may be significant for medium/large diagrams.

Early experiments on this topic show that GEF requires the Viewer to be attached to a Scene before it is rendered. However, this is only required because Gestures attach event listeners to the Scene. It is possible to slightly delay Gestures initialization, i.e. replace:

  • Attach scene
  • Initialize viewer
    • Initialize gestures

With:

  • Initialize viewer
  • Attach scene
  • Initialize gestures

However this requires changes in GEF (Or to override/replace the default GEF Viewer and Gestures initialization, but it would probably be better & easier to just patch GEF directly).

A few bugs remain with this approach (Maybe related to the FX-in-SWT integration, or some bugs somewhere in the JavaFX/GEF/PapyrusFX stack - the exceptions were inconsistent), especially in the refreshVisuals() methods. I didn't investigate this much further, but I mostly got it working by skipping refreshVisuals() in the initialization phase, and only calling it after the Viewer is attached to a Scene.

[Interactions] Implement a Palette for creating Nodes and Edges

The diagram should include a Palette allowing creation of Nodes and Edges.

In the future, we may support additional actions, such as custom selection tools, a deletion tool... as well as different presentation modes (List, grid, details list...), but that's out of the scope for the first version.

[Interactions] Improve multi-selection interactions

Currently, interactions in multi-selection are handled with a naive iteration. This works fine when the selected elements don't depend on each other, but causes inconsistencies when e.g. moving elements nested in each other.

For example, moving a Package and one of its contained Classes will move the class twice as far. Similar inconsistencies happen for anchored elements (e.g. moving an Association Label together with the Class to which the Association is connected)

The top-level policy (MoveOnDragHandler) should pre-filter selected elements to remove dependents. The actual individual policy (e.g. MoveNodeHandler, MoveConnectionLabelHandler) should probably still be responsible for the final decision, i.e. whether the element needs to be moved at all or if it should be ignored.

We may need to pass additional parameters to the Handlers (Similar to GEF 3 Requests?) to handle this case: the handlers need access to the full selection (even if they are expected to work on a single element), and potentially additional (arbitrary) parameters

[Dependency Injection] Define a mechanism to Inject Activatable without Adapters

Currently, when we want to inject a service tightly coupled to a Part (e.g. because it needs to install listeners upon part activation), we need to go through IAdapters.

Injecting IAdapters means we need to go through the AdapterMapBinder, which doesn't allow duplicate keys, thus making it difficult to override generic adapters (Installed by default, either in the generic module, or on more abstract parts) with specific adapters. Roles help, but when several adapters are installed for the same interface, it's not clear how to find the correct one only based on roles (What we want to do is to use only the most specific adapter, so a priority-based mechanism would work best; roles don't really support that)

Moreover, Adapters can't be referenced with a simple @Inject, even when using our custom PartScope. Also, Parts are injected first, then activated asynchronously. So the PartScope is no longer active upon part activation.

So we need a clear mechanism to inject Activatable in Parts, which are not Adapters (They may be adapters, if we find a way to make it work properly with roles, e.g. with a fixed pool of priorities, but that doesn't scale well).

We also need to strictly clarify the priorities, especially when overriding Activatables on two dimensions: specific modules, and specific target parts. (GEFFxModule vs GMFModule/UMLModule/SpecificUMLDiagramModule, and BaseContentPart vs NodeContentPart/ConnectionContentPart/etc.)

Currently, the workaround is to use two distinct roles: any custom role for low-priority, and AdapterKey.defaultRole() for highest priority. However, this limits us to exactly two levels (Since we don't know how to prioritize custom roles between each other). Such workarounds can be found e.g. in GMFModule#bindStyleAdapters, and also in GEFFxModule (Any binding using AdapterRoles.fallbackRole())

[Renderer] Packages are not properly displayed on startup

The way Shapes are applied to the Nodes are problematic. This is especially true for the Package Shape.

This Shape should adapt to the layout bounds of its Node. The default in JavaFX is that the Shape is resized proportionally to its Node Bounds; but for Package, we don't want that: we actually need to recompute the complete Path/Shape. This is required because the Label has a fixed size that depends on the text (And font, line-wrapping, etc.) while the rest of the path depends on the size of the entire node. Their are also min/max to be respected, so that e.g. the body is always at least slightly larger than the header (And probably higher, too).

Comments/constraints should also be updated similarly, because the bent corner needs a fixed size, whereas the rest of the body should follow the bounds of its Node.

In general, these custom shapes should be reworked to render properly under any circumstances.

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.