# Renkan - Client configuration

Renkan is a tool to simply build oriented graphs by creating nodes and drag'n'droping links,
pictures and html elements from web pages. Each node can have title, description, uri/url, color,
image and specific size. Each node can have title, uri/url and color.


## Embedding Renkan in a web page

Whatever configuration you have, you need to import those javascript files **in that order**...

```html
<script src="[...]/jquery.min.js"></script>
<script src="[...]/jquery.mousewheel.min.js"></script>
<script src="[...]/underscore-min.js"></script>
<script src="[...]/backbone.js"></script>
<script src="[...]/backbone-relational.js"></script>
<script src="[...]/paper.js"></script>
<script src="[...]/renkan.js"></script>
```

... and the renkan css file :

```html
<link rel="stylesheet" href="[...]/renkan.css" />
```

Finally, add the div in you DOM :

```html
<div id="renkan"></div>
```

Your Renkan should be displayed. Now let's see more specifically the 2 displays possibilities : in body 100% or in a div with set width and height.

N.B. : renkan.js is the concatenation of those js files : header.js main.js models.js defaults.js i18n.js paper-renderer.js full-json.js ldtjson-bin.js list-bin.js wikipedia-bin.js.
It is built with the script available in sbin/build/compil.sh.

### In body 100%

Nothing to add, the html is very simple :

```html
<body>
    <div id="renkan"></div>
</body>
```

### In a div

The renkan div has the css attributes position:absolute/top:0/left:0/bottom:0/right:0,
so the parent div has to be in position:relative and define width and height. Here is a simple example including css and partial html :

```html
<head>
  <style type="text/css">
    body{
        margin: 0 auto;
        width: 960px;
    }
    .header, .footer {
        font-size: 14px;
        height: 40px;
        padding-top: 10px;
    }
    .rnk-container{
        height: 500px;
        position: relative;
        width: 700px;
    }
  </style>
</head>
<body>
  <div class="header">
    This is a header
  </div>
  <div class="rnk-container">
     <div id="renkan"></div>
  </div>
  <div class="footer">
    This is a footer
  </div>
</body>
```

## Embedding a read only Renkan

To embed a read only Renkan, just add this script tag :

```html
<script type="text/javascript">
    var _renkan;
    $(function() {
        _renkan = new Rkns.Renkan({
            editor_mode: false,
            show_bins: false,
        });
        Rkns.jsonIO(_renkan, {
            url: "any_local_or_jsonp_url"
        });
    });
</script>
```


## Embedding a writable Renkan

### Simple mode : no bins on the left, just the canvas

To embed a simple writable Renkan, just add this script tag. In the client folder, "data/simple-persist.php" makes a very simple persistent url.
The persistent url is supposed to give the json data on GET request at page load, and save datas at PUT request sent by the browser :

```html
<script type="text/javascript">
    var _renkan;
    $(function() {
        _renkan = new Rkns.Renkan({
            show_bins: false
        });
        Rkns.jsonIO(_renkan, {
            url: "url_of_a_persistent_connection"
        });
    });
</script>
```


## Search and bins

On the right of your renkan interface, you can add some search engine and data bins.

Search engine can be the current [IRI's Lignes de temps platform](http://ldt.iri.centrepompidou.fr/) and wikipedia in any available language.
Here is an example of configuration :

```js
_renkan = new Rkns.Renkan({
    search: [
            {
                type: "Ldt"
            },
            {
                type: "Wikipedia",
                lang: "fr"
            },
            {
                type: "Wikipedia",
                lang: "ja"
            }
    ]
});
Rkns.jsonIO(_renkan, {
    url: "data/simple-persist.php"
});
```

You can also define data bins : annotations loaded from IRI's Lignes de temps projects, and any resources which can be drag and dropped into the renkan.
Resources can be simple texts, links or objects with title, description, url and image. Here is an example of configuration :

```js
_renkan = new Rkns.Renkan({
    search: [
        ...
    ],
    bins: [
        {
            title: "To be or not to be on Lignes de Temps",
            type: "Ldt",
            ldt_type: "Project",
            project_id: "6af4019c-8283-11e2-9678-00145ea4a2be",
            ldt_platform: "http://ldt.iri.centrepompidou.fr/"
        },
        {
            type: "ResourceList",
            title: "Ressources",
            list: [
                {
                    url: "http://www.google.com/",
                    title: "Google",
                    description: "Search engine",
                    image: "http://www.google.fr/images/srpr/logo4w.png"
                },
                "Polemic Tweet http://www.polemictweet.com",
                "Twitter http://www.twitter.com/"
            ]
        }
    ]
});
Rkns.jsonIO(_renkan, {
    url: "data/simple-persist.php"
});
```


If you embed the renkan in a div, the renkan container css should have overflow:hidden in order to hide bins when the user wants to.

## More configuration

You can configure several things :
* the language of your interface, english (default) or french
* you can fill your nodes with black color instead of transparent.
* thanks to an external file, you can define properties for links between node.

```js
_renkan = new Rkns.Renkan({
    ...
    property_files: [ "data/properties.json" ],
    node_fill_color: true,
    language: "fr"
});
```

Here is an example of properties file :

```json
[
    {
        "label": "Dublin Core Metadata",
        "base-uri": "http://purl.org/dc/elements/1.1/",
        "properties": [
            {
                "uri": "creator",
                "label": "created by"
            }, {
                "uri": "date",
                "label": "has date"
            }, {
                "uri": "subject",
                "label": "has subject"
            }
        ]
    }, {
        "label": "SKOS Semantic relations",
        "base-uri": "http://www.w3.org/2004/02/skos/core#",
        "properties": [
            {
                "uri": "broader",
                "label": "has broader"
            }, {
                "uri": "narrower",
                "label": "has narrower"
            }, {
                "uri": "related",
                "label": "has related"
            }
        ]
    }
]
```


Finally, here is an example of full configuration :

```html
<script type="text/javascript">
    var _renkan;
    $(function() {
        _renkan = new Rkns.Renkan({
            search: [
                {
                    type: "Ldt"
                },
                {
                    type: "Wikipedia",
                    lang: "fr"
                },
                {
                    type: "Wikipedia",
                    lang: "ja"
                }
            ],
            bins: [
                {
                    title: "Projet Lignes de Temps",
                    type: "Ldt",
                    ldt_type: "Project",
                    project_id: "6af4019c-8283-11e2-9678-00145ea4a2be",
                    ldt_platform: "http://ldt.iri.centrepompidou.fr/"
               },
                {
                    type: "ResourceList",
                    title: "Ressources",
                    list: [
                        {
                            url: "http://www.google.com/",
                            title: "Google",
                            description: "Search engine",
                            image: "http://www.google.fr/images/srpr/logo4w.png"
                        },
                        "Polemic Tweet http://www.polemictweet.com",
                        "Twitter http://www.twitter.com/"
                    ]
                }
            ],
            property_files: [ "data/properties.json" ],
            node_fill_color: false,
            language: "fr"
        });
        Rkns.jsonIO(_renkan, {
            url: "data/simple-persist.php"
        });
    });
</script>
```

## Url Parameters

Renkan accepts few Hash parameters allowing you to change the view, navigate in the map, highlight some nodes, etc. (e.g: http://myrenkan.com/renkan1/#?viewIndex=2&idNode=12345)
Here is an exhaustive list of these parameters:
* viewIndex=index: init the renkan with the indexed view. Negative index starts from the end of the list of views (viewIndex=-1 will load the last view). In case the view doesn't exist, the initial view (viewIndex=0) will be loaded.
* view=offset-x,offset-y,zoom-level: Load a view with the given zoom and offset parameters
* view=autoscale: force the view to be autoscaled when the renkan loads
* idNode=id: highlight a node according to the given node id.

## Drop management

You can override, partially or totally, the function that handle the drop event from an other web page.
The current function catches drops from google results page, tweets, links, images and other things like svg paths.
If you want to override totally the handler function, you can define a **drop\_handler** function that receives a \_data object
and returns a node object. A node object has title, description, image and uri properties. The \_data object is received from the
browser's drop event. Here is an example of drop\_handler function :

```js
_renkan = new Rkns.Renkan({
    ...
    drop_handler: function(_data){
        var newNode = {};
        newNode.title = "Overridden title";
        newNode.description = "Overridden description " + _data["text/plain"];
        return newNode;
    }
});
```

You can also define a **drop\_enhancer** function that receives the already formed node object and \_data object. This function has to
return the overriden node object. Here is an example of drop\_enhancer function :

```js
_renkan = new Rkns.Renkan({
    ...
    drop_enhancer: function(newNode, _data){
        newNode.title = "Prefixed title : " + newNode.title;
        return newNode;
    }
});
```

## Data and api

### Data

The data exchanged by Renkan is a json object ths following structure:
(Warning: some fields are optionals, and )

```json
{
    "id": "f4d002b7-d4fd-486c-8898-6c6ceebc3354",
    "schema_version": 2, #version of schema, latest is 2.
    "title": "Example of Renkan with movies",
    "description": "A long description",
    "created": "2013-03-18T11:32:40.253+01:00",
    "updated": "2014-02-04T15:12:56.619+01:00",
    "nodes": [
        {
            "id": "node-2013-05-08-72c911bafdf9932c-0001",
            "title": "Une femme mène l'enquête",
            "description": "La caméra suit la femme qui marche\nJeu avec la caméra qui se substitue au spectateur",
            "uri": "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/lyceehulst_3extraits/c8a61ee4-b33c-11e2-802c-00145ea4a2be#id=s_DCA8D184-EFC2-314B-0F6B-84043E8F9984",
            "style": { #optional
                "color": "#ff7f00", #line color, optional (null)
                "thickness": 1, #thickness of the line, optional (1)
                "dash": false, #dashed line, optional (false)
            },
            "position": {
                "x": -547.0499881440252,
                "y": -221.5401229374163
            },
            "image": "http://ldt.iri.centrepompidou.fr/static/site/ldt/css/imgs/video_sequence.png",
            "size": 0,
            "project_id": "f4d002b7-d4fd-486c-8898-6c6ceebc3354",
            "created_by": "de68xf75y6hs5rgjhgghxbm217xk",
            "type": "...",
            "hidden": false,
            "shape": "circle",
        },
        ...
    ],
    "edges": [
        {
            "id": "edge-2013-05-08-72c911bafdf9932c-0002",
            "title": "",
            "description": "",
            "uri": "",
            "style": { #optional
                "color": "#ff7f00", #line color, optional (null)
                "thickness": 1, #thickness of the line, optional (1)
                "dash": false, #dashed line, optional (false)
                "arrow": true,  #draw the arrow, optional (true)  
            },
            "from": "node-2013-04-30-a81adec6694db5f4-0032",
            "to": "node-2013-05-08-72c911bafdf9932c-0001",
            "project_id": "f4d002b7-d4fd-486c-8898-6c6ceebc3354",
            "created_by": "de68xf75y6hs5rgjhgghxbm217xk"
        },
        ...
    ],
    "users": [ #optional
        {
            "userId": "user-2015-05-05-72c911bafdf9932c-0001",
            "color": "#cc9866",
            "username": "user1",
            "anonymous": true
        },
    ...
    ],
    "space_id": "17f968e4-2640-4319-aa61-b5b8b527ebb4", #Optional
    "views": [ #Optional
        {
            "zoom_level": 0.8275032552816195,
            "offset_x": 832.0104075533723,
            "offset_y": 402.8917139487223
        }
    ]
}
```

This data is a direct json serialisation of the data model (cf `client/js/`).


### IO module and server communications

Currently 2 modules are defined to load and save data:
  - save-once: data is loaded by ajax at the page initialization and saved each time the save button is clicked (floppy disc icon)
  - full-json: data is loaded by ajax at the page initialization and saved each time the data is modified.

The code of these 2 modules is rather simple and easy to adapt. the various examples in the `test` folder show how to configure them.
Both these 2 modules communicate with the server with a single endpoint. The communication is made with JSON documents and is bidirectional: 'GET' to load the project, 'POST' to send back the modified project.
the dev environement (see [dev](#dev)) offer a simple implementation of such an endpoint for testing support. The code of this endpoint is in the file `client/data/simple-persist.js`.


## <a name="dev"></a>Dev

Renkan offers a dev environment that uses [Grunt](http://gruntjs.com/) for running tasks and [Bower](http://bower.io/) for managing dependencies.

### Setup

The only prerequisite is to install [nodejs](https://nodejs.org/) or [iojs](https://iojs.org/en/index.html). Once installed, the complete dev environment can be obtained with the following commands:

```sh
$ npm i
$ ./node_modules/.bin/bower install
```


### Grunt tasks

We offer a environment to develop without having to build all the project manually after each change. We define few grunt task to help us
making it easier. You can launch them by running `./node_modules/.bin/grunt <task>`.

* `dev`: will build the project but keep the temporary file like templates.js to let us test the application through the test files (see ['Tests'](#tests) part below). Then it will launch a small web server for testing and watch the modifications of the js/css/html to build the project again in case of any change. The test server runs on port 9001 on your local machine i.e. http://localhost:9001 . The folder served is the `client/` folder.

Tasks for production :
* `default`: will build the project and clean the temporary files (like templates.js) used during development and building.
* `copy-server`: will copy the built project to the server part of this project.


## <a name="tests"></a>Tests

Because of a simple php file enabling persistent connection, you can not test the writables examples by only opening them in your browser.
A url like file:///path/to/folder/test-writable-\*.html will not work.
You need to run a localhost server that executes php and go to a url like http://localhost:9001/test/test-writable-\*.html. (cf. [Dev](#dev) above)

For read only examples, it appears that for security reasons urls like file:///path/to/folder/test-readonly-\*.html only work on Firefox.
To see those examples with other browsers, you also need to run a localhost server and go to a url like http://localhost:9001/test/test-readonly-\*.html. (cf. [Dev](#dev) above)
