-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from Webiks/no-angularjs
Migrating away from AngularJS
- Loading branch information
Showing
53 changed files
with
11,754 additions
and
4,253 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,4 @@ | ||
logs/* | ||
!.gitkeep | ||
.idea/ | ||
dist/ | ||
node_modules/ | ||
bower_components/ | ||
tmp | ||
.DS_Store | ||
.idea | ||
desktop.ini | ||
.travis.yml | ||
npm-debug.log | ||
src/app/TILDOCS-#40699695-v1-ùàâ æëåëàì.docx | ||
*.docx | ||
coverage/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
language: node_js | ||
node_js: | ||
- 8 | ||
before_script: | ||
- export DISPLAY=:99.0 | ||
- sh -e /etc/init.d/xvfb start | ||
script: webpack && npm run test-ci | ||
|
||
deploy: | ||
- provider: releases | ||
api_key: | ||
secure: QXZMJz8xt2JK1SuZ5AkVHx6Orb2Ebkb5Lc5YxkrxgWu+xbt6lGAy8mMvj2ytkAu2OuecGtAsnh8tiYVJ6LW7d2fGBDgAjSAL1ZSPi+4GQrddwlTkZ8AfGvCLu9no/+E9G2rpDHixmt+lPUbtCfLbdkQ2WCX4gPKcsUdCHcgZvGb9vGADsMNoDwXM0fGiiBr5FlfcwxH3cL60LX3weJRQMseOXAAxMH9syiu9XHjJNt/Ty/p+xZOCK0NxOzQLp2KYONpuLI86+Hdb+bmgIWlwRHvDa1CgdzXbLl9zqea1fHUxsT9g5GM5jX344Q/SOKsoSdtvb2ddbtsm5IJ23EiiL0muhRjudpyRE48gtkPZUhItB539hrdOHWXtWmNxHu715xU16j4YiyO5J/N6ZThJT8WMcTnEHIJVXSVQTPYTyj6Bl3dQFWUBzyKRO9l2LeueEI2kAEAFa5cd31om/XaQmVNK/CFLz7FR6x7o4/Bvd2aCeI2gQ7eRlJXixYC6px6MdgB7yd5BPQcfDeOeefm5bEqrKWr17OIq//UQEkBmO3OJAKdUN9SNOIjV2DUBwbr7kL1vTosdGzJ0xDSUDmmxrX9SZw7HRY33Whle/GLfloGwo1TVdTgbic1TRO9dxtPhdxd6mY+FAaPFUQBYDNzwnXhxJFEeMKZUDIVqI+MtICA= | ||
skip_cleanup: true | ||
file: dist | ||
on: | ||
tags: true | ||
- provider: npm | ||
email: amitmoryossef@gmail.com | ||
api_key: | ||
secure: WZml/wR8HFO8PSweGV9/W5GzzK2Jix8AUAi+B2HNUDtEn4YjuHjSY4DQkrkIaRSUNktAIA59TQIhJCUoYu+movuGOr/E9VFBqftYaZb+78y98mK0Z1As07feZUs36o3gFNs0qKhNyrMAXaDgqH75Cp6qL6F9B46iTdXkvVb351BWkzX7/B8w7BnfBLWYj8Q+Tt74wR+b/TuVBjYK7LJLtxWGvIOc23984z8S+yxIRmsZVabyZE+8MHavGyQ1Jg/5/dLKQohjzylVK3mlz1j/WlHSl5M46P6gjhbeGLrmImcANWXJI7G31v4h2wP0AnIWYuBIwuAv4RE/ovWy1jl+MY7Go1jubHBusPMnn6w7UTvDxgRdVfp8JCm9H7iHkfKgBLQGDB2DF9aquqC3H7jrH0KX4sbIJs5f0z24iEkQtXMVpHVtSJqbbMeP1OQSlUW6bJifmYmNS6+e61atulf8Ag9XuBK2GjbLD/Tug40LUnjq9zPa7Z1bJxFOCfFif0VLmNJ12aFQZLuCBaxRC+rupWPDM/WzK+7h+HamQFHgX3UG6uW1s6ARv8ymNNRUD5UJTB3TfMK+E/ygoiTHLzfwULgV8XyPpSnEUdyQDDit2tl6IqTpZFTU2ZsaqNH2ew0lKHUFcXHNlhaAIvlXMbtQyV50WO20QDnUsQzl2D5yhz4= | ||
skip_cleanup: true | ||
on: | ||
tags: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Revisiting Force-Horse: Making a Legacy Plugin Agnostic and Usable | ||
For a while, we at Webiks used our own AngularJS D3.js library for graphs visualizations of real-life data sets, called "[Force-Horse](https://github.com/Webiks/force-horse)". | ||
|
||
Force-Horse is an open source Javascript component wrapping a Force Layout and adding some functionalities we found very useful, like Adaptive tuning of forces and constraints parameters, Adaptive rendering cycle, Play/Pause the simulation, Multiple edges between two nodes, Weight the nodes and the edges, etc... | ||
|
||
 | ||
|
||
While you can read all of the details on the library in Ram's [blog post](http://webiks.com/force-horse-force-layout-component/), the gist of it is having a library that adapts to many types of data, is easily modifiable for developers, supports large data sets, and easily allowing customization of the base SVG's design. | ||
|
||
## So... What's New? | ||
Having the library written using AngularJS, forces the user to use a legacy framework. Either the user thinks they can just include AngularJS in the bundle, increasing the bundle, or trying to implement the component for their used framework. | ||
Therefore, we decided to remove the dependency for AngularJS, making the library framework agnostic. | ||
|
||
##### Agnostification | ||
We migrated AngularJS out of the library, moving to a standard browser feature - [Custom Elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements), being adopted by most modern browsers. (In case it isn't supported att the moment, there is a tiny [browser polyfill](https://github.com/webcomponents/webcomponentsjs) - see [browsers support](https://caniuse.com/#search=custom%20elements%20v1)) | ||
What we love about using Custom Elements, is that all of the main frameworks - Angular, React, Vue, Polymer etc.. - support it for bindings of inputs and outputs, but you don't have to use a framework to use it. | ||
|
||
##### Integration | ||
We also made the component much easier to integrate, now creating 2 bundles - one for Javascript and one for CSS - and loading the images as a base64 mask directly inside the CSS, so there is no need when creating a distribution build to copy our assets anymore, just importing our CSS. | ||
|
||
##### Tests | ||
The original AngularJS component did not have many tests, so we could not ensure it was working for every user. Now, we added many unit tests for many use cases, to cover all of the grounds we need to be confidant in the stability of this awesome component. | ||
For continues integration we now use Travis-CI, to automatically test and deploy the package. | ||
|
||
##### Standards | ||
It's 2017, so we ditched the old ES5 syntax, migrating the entire Javascript code base to ES6, taking advantage of the great things it offers. | ||
Also, we moved from CSS to SCSS, for better style management and versatility. | ||
|
||
##### Usage | ||
Using Force-Horse is now as simple as using any other element. The new usage guide can be found in the [README](https://github.com/Webiks/force-horse). | ||
|
||
### Wanna Help? | ||
- Working on something similar? [Contribute to our GitHub project](https://github.com/webiks/force-horse) | ||
- Thinking there is something we can improve on? [Let us know](https://github.com/webiks/force-horse/issues) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,105 +1,145 @@ | ||
# force-horse | ||
|
||
An angular.js wrapper for a d3.js force fayout | ||
|
||
#### USAGE | ||
|
||
force-horse is implemented as an angular.js 1.4 directive. It can be used either as an HTML element or as an HTML element attribute. | ||
|
||
`<force-horse options=”ctrl.options”></force-horse>` | ||
|
||
or: | ||
|
||
`<div force-horse options=”ctrl.options”></div>` | ||
|
||
A force-horse element does not have an intrincsic size. It adapts itself to the size that is set by its parent. force-horse is implementing CSS **flex-box** display logic. | ||
## Usage | ||
### Installing | ||
`npm install --save force-horse` | ||
### Loading: | ||
With a modules bundler (recommended): | ||
```js | ||
import 'force-horse'; // Imports the web component, not compiled | ||
// OR | ||
import 'force-horse/dist/main.bundle.js'; // Compiled. Less recommended because can't dedupe | ||
``` | ||
```scss | ||
@import 'force-horse/src/index.scss'; // Imports the SCSS index file, not compiled | ||
// OR | ||
@import 'force-horse/dist/style.bundle.css'; // Imports the bundle as CSS, compiled | ||
``` | ||
Directly from HTML: | ||
```html | ||
<link rel="stylesheet" type="text/css" href="node_modules/force-horse/dist/style.bundle.css" /> | ||
<script type="application/javascript" src="node_modules/force-horse/dist/main.bundle.js"></script> | ||
``` | ||
### Using: | ||
From the template | ||
```html | ||
<!-- Web component --> | ||
<force-horse data='{"nodes": [], "links": []}' config='{"anything": true}'></force-horse> | ||
<!-- Angular: Note that you have to add CUSTOM_ELEMENTS_SCHEMA --> | ||
<force-horse [attr.data]="data | json" [attr.config]="config | json"></force-horse> | ||
``` | ||
From Javascript: | ||
```js | ||
const forceHorse = document.createElement("force-horse"); | ||
forceHorse.setConfig(someConfig); | ||
forceHorse.setData(someData); | ||
someContainer.appendChild(forceHorse); | ||
``` | ||
|
||
# Options parameters | ||
To be rendered, force-horse must first get `data`, which can be passed as an attribute, or directly using `setData` | ||
|
||
Parameters are passed through the options attribute. Currently, this object contains only the data property, which holds the graph's data in the following format: | ||
A force-horse element does not have an intrinsic size. It adapts itself to the size that is set by its parent. | ||
force-horse is implementing CSS **flex-box** display logic. | ||
|
||
**data**: the graph data (nodes and links): | ||
``` | ||
# Attributes | ||
## Data | ||
The graph's data (nodes and links): | ||
```json | ||
{ | ||
nodes: [], | ||
edges: [] | ||
"nodes": [], | ||
"links": [] | ||
} | ||
``` | ||
|
||
# API | ||
After initializing the directive, force-horse inserts an object into the `options` object sent to it. This **`forceHorseInstance`** holds inside the force horse API methods. There is one **`forceHorseInstance`** per directive initialized: | ||
|
||
**addEventListener** - accepts an event name (String) and a callback (function). For a list of events see **Events** section below. | ||
## Config | ||
Configure options in the component. Defaults to: | ||
```json | ||
{ | ||
"showButtons": true, | ||
"showLabels": true, | ||
"numOfLabelsToShow": 10, | ||
"showNodeWeight": true, | ||
"showEdgeWeight": true, | ||
"hideOrphanNodes": false, | ||
"showFilterButton": true, | ||
"showLabelsButton": true, | ||
"showNodeWeightButton": true, | ||
"showEdgeWeightButton": true, | ||
"showOrphanNodesButton": true, | ||
"forceParameters": { | ||
"friction": 0.5, | ||
"charge": -100, | ||
"linkStrength": 1, | ||
"gravity": 0.3, | ||
"linkDistance": 10 | ||
} | ||
} | ||
``` | ||
|
||
# API | ||
You can use the API by querying the `force-horse` element, and accessing `viewer`. | ||
```js | ||
// In JS | ||
const viewer = document.qeurySelector("force-horse").viewer; | ||
|
||
// In Angular | ||
// Template: `<force-horse #fh></force-horse>` | ||
@ViewChild('fh') forceHorse: ElementRef; | ||
ngAfterViewInit() { | ||
const viewer = this.forceHorse.viewer; | ||
} | ||
``` | ||
|
||
# Events | ||
# Outputs | ||
|
||
These are the current events. PR's and suggestiong for more are welcome: | ||
**hover**: a node/link is hovered upon | ||
Outputs are event emitters. You can subscribe and unsubscribe in the following way: | ||
``` | ||
const subscription = viewer.hoverEvent.subscribe(() => { /* some callback */); | ||
subscription.unsubscribe(); | ||
``` | ||
|
||
**select**: a node/link is selected | ||
These are the current events. PR's and suggestions for more are welcome: | ||
**ready** (`readyEvent`): an SVG is drawn and ready | ||
|
||
**dblclick**: a node/link is double-clicked upon | ||
**hover** (`hoverEvent`): a node/link is hovered upon | ||
|
||
**filter**: remove the selected nodes/links from the graph | ||
**select** (`selectEvent`): a node/link is selected | ||
|
||
# External Config file | ||
force-horse supports an external json file, **forceHorse.json**. In this file one can set whether each of the buttons (see below) is displayed or not. | ||
Also, force layout parameters can be set, and thus to override the parameters that force-horse computes automatically, for a specific implementation. | ||
**dblclick** (`doubleClickEvent`): a node/link is double-clicked upon | ||
|
||
The config parameters are: | ||
``` | ||
{ | ||
"showLabels": false, //show labels on start | ||
"showNodeWeight": false, // show each node weight or uniform size | ||
"showEdgeWeight": false, // show each edge weight or uniform size | ||
"showFilterButton": true, // show the filter toggle button | ||
"showLabelsButton": true, // show the labels toggle button | ||
"showNodeWeightButton": true, // show the nodes weights toggle button | ||
"showEdgeWeightButton": true, // show the edges weights toggle button | ||
"useEdgesWeights": false, //weather to use edges weights or simple edge sum for node weights | ||
"forceParameters": { | ||
"charge": -350, | ||
"linkStrength": 1, | ||
"gravity": 0.2, | ||
"linkDistance": 10, | ||
"friction": 0.5 | ||
} | ||
} | ||
``` | ||
**filter** (`filterEvent`): remove the selected nodes/links from the graph | ||
|
||
The forceHorse project contains a complete **demo application**. The demo application is also available on the [plunker](http://embed.plnkr.co/SYmehtaAnQVyMpLJJY2B/?show=preview) site. | ||
The forceHorse project contains a complete **demo application**. The demo application is also available on the [plunker](http://embed.plnkr.co/SYmehtaAnQVyMpLJJY2B/?show=preview) site. | ||
|
||
#### VISUAL INTERFACE | ||
On activation, force-horse shows the given graph. The graph stabilizes after a short force simulation. Then, if needed, it **zooms** out, so that the whole graph can be seen at a glance. | ||
|
||
On activation, force-horse shows the given graph. The graph stabilizes after a short force simulation. Then, if needed, it **zooms **out, so that the whole graph can be seen at a glance. | ||
|
||
Beside showing the graph itself, force-horse provides visual indication of **hovering **over a node/link, and of **selecting **a node/link. It supports node **dragging**, and also **pan **and **zoom**. | ||
Beside showing the graph itself, force-horse provides visual indication of **hovering** over a node/link, and of **selecting** a node/link. It supports node **dragging**, and also **pan** and **zoom**. | ||
|
||
In addition, force-horse is providing the following buttons: | ||
* **filter**: remove selected nodes/links from the graph | ||
* **pause/play**: allows to “freeze” the graph, to locate nodes without subsequent changes by the force-layout simulation | ||
* **home**: automatically pan/zoom so that the whole graph can be seen at a glance | ||
* **labels**: show/hide node labels | ||
* **node weight**: show/hide node weight (weightier nodes will be larger) | ||
* **link weight**: show/hide link weight (weightier links will be thicker) | ||
* **link weight**: show/hide link weight (weightier links will be thicker) | ||
|
||
#### DEPENDENCIES | ||
|
||
The only dependencies of force-horse are: | ||
* **angular.js** v1.4 | ||
* **d3.js** v4 | ||
The only dependency of force-horse is: | ||
* **d3.js** v4 | ||
|
||
#### PERFORMANCE | ||
|
||
force-horse was designed for high performance. Some of the measures in use are: | ||
* minimal use of angular **$watch**’es | ||
* large graphs are not rendered continuously, but only a few times during the force simulation. The screen rendering is controlled programmatically, implementing javascript**requestAnimationFrame**(). A thin **progress bar** is displayed, during a force simulation, so that even if rendering is held, the user can know the stage and the pace of the current force simulation. | ||
* minimal use of DOM manipulations | ||
* large graphs are not rendered continuously, but only a few times during the force simulation. The screen rendering is controlled programmatically, implementing javascript**requestAnimationFrame**(). A thin **progress bar** is displayed, during a force simulation, so that even if rendering is held, the user can know the stage and the pace of the current force simulation. | ||
|
||
#### MULTIPLE LINKS BETWEEN TWO NODES | ||
|
||
The ability to compute multiple, parallel link between two nodes is not currently supported intrinsically by d3.js. It was also not yet developed by the users community. Therefore, we developed this ability especially for force-horse. For the mathematical and implementation details, see [here](http://webiks.com/d3-js-force-layout-straight-parallel-links/). | ||
The ability to compute multiple, parallel link between two nodes is not currently supported intrinsically by d3.js. It was also not yet developed by the users community. Therefore, we developed this ability especially for force-horse. For the mathematical and implementation details, see [here](http://webiks.com/d3-js-force-layout-straight-parallel-links/). | ||
|
||
#### CONSOLE MESSAGES | ||
|
||
Set localStorage.setItem('forceHorse', 'on') to get informative console messages from force-horse. | ||
Set `localStorage.setItem('force-horse', true)` to get informative console messages from force-horse. | ||
To turn it off, remove that item by doing `localStorage.removeItem('force-horse')` |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.