[recline]: Delete old files and code

This commit is contained in:
Rising Odegua
2021-03-15 14:04:56 +01:00
parent b599fe4643
commit 856df4053f
268 changed files with 0 additions and 108993 deletions

View File

@@ -1,148 +0,0 @@
---
layout: container
title: Backends
root: ../
---
<div class="page-header">
<h1>
Backends
<small>Connect to data sources</small>
</h1>
</div>
Backends connect Dataset and Documents to data from a specific 'Backend' data
source. They provide methods for loading and saving Datasets and individuals
Documents as well as for bulk loading via a query API and doing bulk transforms
on the backend.
<div class="alert alert-info">Looking for quickstart tutorial rather than reference documentation? See the <a href="tutorial-backends.html">Backends Tutorial</a>.</div>
Backends come in 2 flavours:
* Loader backends - only implement fetch method. The data is then cached in a
Memory.Store on the Dataset and interacted with there. This is best for
sources which just allow you to load data or where you want to load the data
once and work with it locally.
* Store backends - these support fetch, query and, if write-enabled, save.
These are suitable where the backend contains a lot of data (infeasible to
load locally - for examples a million rows) or where the backend has
capabilities you want to take advantage of.
Examples of the 2 types of backends are provided by the Google docs backend (a
"Loader" backend) and the ElasticSearch backend (a Store backend).
# Available Backends
You can find a list of the available Backends along with examples of how to use
them in the [Backends Tutorial](tutorial-backends.html).
Note that it's easy to write your own backend - you just need to implement the
Recline Backend API described below.
# Backend API
Backend modules must implement the following API:
{% highlight javascript %}
__type__: 'name-of-backend' // e.g. elasticsearch
// Initial load of dataset including initial set of records
fetch: function(dataset)
// Query the backend for records returning them in bulk.
// This method will be used by the Dataset.query method to search the backend
// for records, retrieving the results in bulk.
query: function(queryObj, dataset)
// Save changes to the backend
save: function(changes, dataset)
{% endhighlight %}
Details of each function below. Note that:
* Each backend function takes a dataset object. This is not a Dataset object
but is simple JS object representation resulting from calling
Dataset.toJSON().
It is required because the Dataset attributes contain details of specific
backend (e.g. url for ElasticSearch etc).
* Each function returns a promise API object - that is something conforming to
the jquery promise API and, in particular, having a done and fail function.
### fetch: function(dataset)
On success, promise callback must return an object with the following structure:
{% highlight javascript %}
{
// (optional) Set of record data
// Either an array of arrays *or* an array of objects corresponding to initial set of records for this object
// May not provided if data only returned by query
records: [...]
// (optional) Set of field data
// Either an array of string or an array of objects corresponding to Field specification (see `Field` above)
fields: { ... } // as per recline.Model.Field
// (optional) metadata fields to set on the Dataset object
metadata: { title: ..., id: ... etc }
// boolean indicating whether to use a local memory store for managing this dataset
useMemoryStore:
}
{% endhighlight %}
### query: function(queryObj, dataset)
`queryObj`: JS object following <a href="models.html#query-structure">Query specification</a> above.
#### Callbacks
On success must return a 'QueryResult' object which has the following structure:
{% highlight javascript %}
{
// total number of results (can be null)
total: ...
// one entry for each result record
hits: [
{
// JS object that can be used to initialize a Record object
}
],
// (optional)
facets: {
// facet results (as per <http://www.elasticsearch.org/guide/reference/api/search/facets/>)
}
}
{% endhighlight %}
The QueryResult is partially modelled on ElasticSearch - see <a
href="https://github.com/okfn/recline/issues/57">this issue for more
details</a>.
### save: function(changes, dataset)
<div class="alert alert-warning">The save function is still being revised and
its API and arguments are subject to change</div>
`changes`: an object with the following structure:
{% highlight javascript %}
{
creates: [ record.toJSON(), record.toJSON(), ... ]
updates: [ ... ]
deletes: [ ... ]
}
{% endhighlight %}
Each key has an array of records (as simple JS objects resulting from a call to
Record.toJSON()) that are in that state.
The backend should take appropriate actions for each case.

View File

@@ -1,64 +0,0 @@
# Extensions
Extensions are Views, Backends or other pieces of code that build on Recline but which do not ship as part of the core distribution. Here we have:
* Instructions on creating an extension
* A list of existing extensions
* **If you have created an extension please add it to the list below**
## Creating an Extension
At its minimum its just a single JS file. However, we suggest a bit more structure:
* Put the extension in its own repo named e.g. recline.view.{viewname} or recline.backend.{backendname}
* Including (essential):
* README.md
* the extension code itself name view.{name}.js or backend.{name}.js (or recline.view.{name}.js etc)
* Optional
* [optional but recommended] a test for the extension
* [optional] one or more demo html files showing your extension in action
You may want to include recline as a submodule for testing purposes if you need some of its code
git submodule add git://github.com/okfn/recline.git
Or you can just pull the latest recline.js directly from: http://okfnlabs.org/recline/dist/recline.js
----
## Views
#### Line graphs in nvd3
Line graphs in [nvd3](http://nvd3.org/)
* https://github.com/Moviri/recline/blob/master/src/extensions/views/view.nvd3.graph.js
* https://github.com/NuCivic/recline.view.nvd3.js
#### Kartograph
Integration with [Kartograph](http://kartograph.org/)
* https://github.com/Moviri/recline/blob/master/src/extensions/views/view.kartograph.js
#### Map View using Ordnance Survey
[http://oslabs.github.com/recline-view-osmap/](http://oslabs.github.com/recline-view-osmap/)
A new map view using the Ordnance Survey OpenSpaces tile service. It supports both the free and paid for (pro) stacks. More info and docs are found on the github project page.
----
## Backends
#### Google Docs
This is the official Google Docs backend for Recline (part of the Recline distribution in v0.5)
https://github.com/okfn/recline.backend.gdocs
#### CouchDB
CouchDB backend for Recline.
https://github.com/okfn/recline.backend.couchdb

View File

@@ -1,69 +0,0 @@
---
layout: default
title: Library - Home
root: ../
---
<div class="container library">
<div class="page-header">
<h1>
Documentation
</h1>
</div>
<p>Building on <a href="http://backbonejs.com/">Backbone</a>, Recline
supplies components and structure to data-heavy applications by providing a
set of models (Dataset, Record/Row, Field) and views (Grid, Map, Graph
etc).</p>
<h2 id="concepts">Concepts and Structure</h2>
<h1><small>The Recline Library consists of 3 parts: Models, Backends and Views</small></h1>
<div class="row">
<div class="col-md-4">
<div class="well">
<h3>Models</h3>
<p>Models help you structure your work with data by providing some standard objects such as Dataset and Record &ndash; a Dataset being a collection of Records. <a href="models.html">More &raquo;</a></p>
</div>
</div>
<div class="col-md-4">
<div class="well">
<h3>Backends</h3>
<p>Backends connect your Models to data sources (and stores) &ndash; for example Google Docs spreadsheets, local CSV files, the DataHub, ElasticSearch etc. <a href="backends.html">More &raquo;</a></p>
</div>
</div>
<div class="col-md-4">
<div class="well">
<h3>Views</h3>
<p>Views are user interface components for displaying, editing or interacting with the data. For example, maps, graphs, data grids or a query editor. <a href="views.html">More &raquo;</a></p>
</div>
</div>
</div>
<img src="https://docs.google.com/drawings/pub?id=1tEKX9ybHZKdPImoy7j_m5x3_b9HzcaU1OnNfQB3F9XQ&amp;w=666&amp;h=405" style="display: block; margin: auto;" />
<h2 id="docs-source">Source Docs (via Docco)</h2>
<div class="row">
<div class="col-md-4">
<h4>Models</h4>
<ul>
<li><a href="src/model.html">Models</a></li>
</ul>
</div>
<div class="col-md-4">
<h4>Dataset Views and Widgets</h4>
<ul>
<li><a href="src/view.multiview.html">MultiView View (plus common view code)</a></li>
<li><a href="src/view.slickgrid.html">Grid View</a> (using the excellent <a href="https://github.com/mleibman/SlickGrid">Slickgrid</a>)</li>
<li><a href="src/view.grid.html">Grid View (no dependencies)</a></li>
<li><a href="src/view.flot.html">Graph View (based on Flot)</a></li>
<li><a href="src/view.map.html">Map View (based on Leaflet)</a></li>
<li><a href="src/view.timeline.html">Timeline View</a> (using the excellent <a href="http://timeline.verite.co/">Verite Timeline</a>)</li>
</ul>
</div>
</div>
</div> <!-- / container -->

View File

@@ -1,325 +0,0 @@
---
layout: container
title: Models
root: ../
---
<div class="page-header">
<h1>
Models
</h1>
</div>
Models help you structure your work with data by providing several objects and
functions. The key ones are Dataset and Record -- a Dataset being a collection
of Records. Additionally, there is a a Field object for describing the columns
of a Dataset, a Query object for describing queries, and a Facet object for
holding summary information about a Field (or multiple Fields).
All the models are Backbone models, that is they extend Backbone.Model. Note,
however, that they do not 'sync' (load/save) like normal Backbone models.
<h2 id="dataset">Dataset</h2>
A Dataset is *the* central object in Recline. Standard usage is:
{% highlight javascript %}
var dataset = new recline.model.Dataset({
// general metadata e.g.
id: ...
title: ...
// information about data source e.g.
url: http://url.to.my.data.endpoint/
// backend string or object
backend: a string identifying the backend we are using - see below
});
// initialize dataset with data from the backend.
dataset.fetch();
// we will now have the following (and more) set up - see below for details
dataset.fields // collection of Fields (columns) for this Dataset
dataset.records // collection of Records resulting from latest query
dataset.docCount // total number of Records in the last query
{% endhighlight %}
### Key Attributes
* records: a collection of `Record`s currently loaded for viewing
(updated by calling query method) - note that this need <strong>not</strong>
be all the records in the dataset (for example, you may have connected to a
source where the complete dataset contains a million records but you have
only loaded a 1000 records)
* fields: (aka columns) is a Backbone collectoin of `Field`s listing all the
fields on this Dataset (this can be set explicitly, or, will be set by
Dataset.fetch()
* docCount: total number of records in this dataset
* backend: the Backend (instance) for this Dataset. (NB: this is a the backend
attribute on the object itself not the backend in the Backbone attributes
i.e. the result of dataset.get('backend'). The latter is a string identifying
the backend.
* queryState: a `Query` object which stores current queryState. queryState may
be edited by other components (e.g. a query editor view) changes will trigger
a Dataset query.
* facets: a collection of `Facet`s
### Querying
{% highlight javascript %}
dataset.query(queryObj)
{% endhighlight %}
`queryObj` is an object following the <a href="#query-structure">query
specification below</a>.
<h2 id="record">Record (aka Row)</h2>
A Record is a single entry or row in a dataset. A Record needs little more than
what is provided by the standard Backbone Model object. In general, you will
never create a Record directly -- they will get created for you by Datasets
from query results.
<h2 id="field">Field (aka Column)</h2>
A Field should have the following attributes as standard:
{% highlight javascript %}
var field = new Field({
// a unique identifer for this field- usually this should match the key in the records hash
id: 'my-field-id'
// (optional: defaults to id) the visible label used for this field
label: 'My Field Name',
// (optional: defaults to string) the type of the data in this field.
// For list of type names see below
type: 'string',
// (optional - defaults to null) used to indicate how the data should be
// formatted. See below.
format: null,
// (default: false) attribute indicating this field has no backend data but
// is just derived from other fields (see below).
is_derived: false
{% endhighlight %}
#### Types
The type attribute is a string indicating the type of this field.
Types are
based on the [type set of json-schmea][types-1] with a few minor additions and
modifications (cf other type lists include those in [Elasticsearch](es-types)).
The type list is as follows (brackets indicate
possible aliases for specific types - these types will be recognized and
normalized to the default type name for that type):
* **string (text)**: a string
* **number (double, float, numeric)**: a number including floating point numbers.
* **integer (int)**: an integer.
* **date**: a date. The preferred format is YYYY-MM-DD.
* **time**: a time without a date
* **date-time (datetime, timestamp)**: a date-time. It is recommended this be in ISO 8601
format of YYYY-MM- DDThh:mm:ssZ in UTC time.
* **boolean (bool)**
* **binary**: base64 representation of binary data.
* **geo_point**: as per
<http://www.elasticsearch.org/guide/reference/mapping/geo-point-type.html>.
That is a field (in these examples named location) that has one of the
following structures:
location: {
lon: ...
lat: ...
}
location: [lon,lat]
location: "lat, lng"
As bonus there is also support for (beyond the ES style geo_point):
// geonames style
location: {
lng: ...
lat: ...
}
// found on the web
location: "(lat, lon)"
* **geojson**: as per <http://geojson.org/>
* **array**: an array
* **object (json)**: an object
* **any**: value of field may be any type
<div class="alert">NB: types are not validated so you can set the type to
whatever value you like (it does not have to be in the above list). However,
using types outside of the specified list may limit functionality.</div>
[types-1]: http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1
[es-types]: http://www.elasticsearch.org/guide/reference/mapping/
#### Rendering, types and formats
One can customize the rendering of fields in the user interface and elsewhere
by setting a renderer function on the field. You do this by setting a field
attribute:
{% highlight javascript %}
myfield.renderer = myRenderFunction;
{% endhighlight %}
Your renderer function should have the following signature:
function(value, field, record)
Where the arguments passed in are as follows:
* `value`: the value of the cell (record value for this field)
* `field`: corresponding `Field` object
* `record`: is the `Record` object (as simple JS object)
Note that implementing functions can ignore arguments (e.g. function(value)
would be a valid formatter function).
To guide the behaviour of renderers we have type and format information.
Example types and formats are:
* type=date, format=yyyy-mm-dd
* type=float, format=percentage
* type=string, format=markdown (render as markdown if Showdown available)
Default renderers are provided - see the source for details, but a few examples
are:
* type = string
* no format provided: pass through but convert http:// to hyperlinks
* format = plain: do no processing on the source text
* format = markdown: process as markdown (if Showdown library available)
* type = float
* format = percentage: format as a percentage
#### Derived fields
Some fields may be 'dervied' from other fields. This allows you to define an
entirely new value for data in this field. This provides support for a)
'derived/computed' fields: i.e. fields whose data are functions of the data in
other fields b) transforming the value of this field prior to rendering.
To use derived fields set a `deriver` function on the Field. This function will
be used to derive/compute the value of data in this field as a function of this
field's value (if any) and the current record. It's signature and behaviour is
the same as for renderer.
<h2 id="query">Query</h2>
Query instances encapsulate a query to the backend (see <a
href="backend/base.html">query method on backend</a>). Useful both
for creating queries and for storing and manipulating query state -
e.g. from a query editor).
<h3 id="query-structure">Query Structure and format</h3>
Query structure should follow that of [ElasticSearch query
language](http://www.elasticsearch.org/guide/reference/api/search/).
**NB: It is up to specific backends how to implement and support this query
structure. Different backends might choose to implement things differently
or not support certain features. Please check your backend for details.**
Query object has the following key attributes:
* size (=limit): number of results to return
* from (=offset): offset into result set - http://www.elasticsearch.org/guide/reference/api/search/from-size.html
* sort: sort order - see below
* query: Query in ES Query DSL <http://www.elasticsearch.org/guide/reference/api/search/query.html>
* filter: See filters and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/filtered-query.html">Filtered Query</a>
* fields: set of fields to return - http://www.elasticsearch.org/guide/reference/api/search/fields.html
* facets: specification of facets - see http://www.elasticsearch.org/guide/reference/api/search/facets/
Additions:
* q: either straight text or a hash will map directly onto a [query_string
query](http://www.elasticsearch.org/guide/reference/query-dsl/query-string-query.html)
in backend
* Of course this can be re-interpreted by different backends. E.g. some may
just pass this straight through e.g. for an SQL backend this could be the
full SQL query
* filters: array of ElasticSearch filters. These will be and-ed together for
execution.
#### Sort
Sort structure is inspired by <http://www.elasticsearch.org/guide/reference/api/search/sort.html> but with some standardization.
Sort structure must be as follows:
"sort" : [
{ field: "post_date", "order" : "desc"},
{ field: "user" },
{ "name" : "desc" },
{ "age" : "desc" },
{"_score": null}
]
If order is omitted it is assumed to be "desc" except in the case of _score.
_score is a special case which is used for match score if that is supported by
the backend.
#### Examples
<pre>
{
q: 'quick brown fox',
filters: [
{ term: { 'owner': 'jones' } }
]
}
</pre>
<h2>Facet <small>&ndash; Summary information (e.g. values and counts) about a field obtained by a 'faceting' or 'group by' method</small>
</h2>
Structure of a facet follows that of Facet results in ElasticSearch, see:
<http://www.elasticsearch.org/guide/reference/api/search/facets/>
Specifically the object structure of a facet looks like (there is one
addition compared to ElasticSearch: the "id" field which corresponds to the
key used to specify this facet in the facet query):
{% highlight javascript %}
{
id: "id-of-facet",
// type of this facet (terms, range, histogram etc)
_type : "terms",
// total number of tokens in the facet
total: 5,
// @property {number} number of records which have no value for the field
missing : 0,
// number of facet values not included in the returned facets
other: 0,
// term object ({term: , count: ...})
terms: [ {
"term" : "foo",
"count" : 2
}, {
"term" : "bar",
"count" : 2
}, {
"term" : "baz",
"count" : 1
}
]
}
{% endhighlight %}

View File

@@ -1,240 +0,0 @@
<!DOCTYPE html> <html> <head> <title>backend.csv.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="backend.csv.html"> backend.csv.js </a> <a class="source" href="backend.dataproxy.html"> backend.dataproxy.js </a> <a class="source" href="backend.memory.html"> backend.memory.js </a> <a class="source" href="ecma-fixes.html"> ecma-fixes.js </a> <a class="source" href="model.html"> model.js </a> <a class="source" href="view.flot.html"> view.flot.js </a> <a class="source" href="view.graph.html"> view.graph.js </a> <a class="source" href="view.grid.html"> view.grid.js </a> <a class="source" href="view.map.html"> view.map.js </a> <a class="source" href="view.multiview.html"> view.multiview.js </a> <a class="source" href="view.slickgrid.html"> view.slickgrid.js </a> <a class="source" href="view.timeline.html"> view.timeline.js </a> <a class="source" href="widget.facetviewer.html"> widget.facetviewer.js </a> <a class="source" href="widget.fields.html"> widget.fields.js </a> <a class="source" href="widget.filtereditor.html"> widget.filtereditor.js </a> <a class="source" href="widget.pager.html"> widget.pager.js </a> <a class="source" href="widget.queryeditor.html"> widget.queryeditor.js </a> <a class="source" href="widget.valuefilter.html"> widget.valuefilter.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> backend.csv.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">recline</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span> <span class="o">||</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span> <span class="o">||</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">CSV</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">CSV</span> <span class="o">||</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>Note that provision of jQuery is optional (it is <strong>only</strong> needed if you use fetch on a remote file)</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">my</span><span class="p">)</span> <span class="p">{</span>
<span class="s2">&quot;use strict&quot;</span><span class="p">;</span>
<span class="nx">my</span><span class="p">.</span><span class="nx">__type__</span> <span class="o">=</span> <span class="s1">&#39;csv&#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>use either jQuery or Underscore Deferred depending on what is available</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">Deferred</span> <span class="o">=</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">jQuery</span> <span class="o">!==</span> <span class="s2">&quot;undefined&quot;</span> <span class="o">&amp;&amp;</span> <span class="nx">jQuery</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">)</span> <span class="o">||</span> <span class="nx">_</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <h2>fetch</h2>
<p>fetch supports 3 options depending on the attribute provided on the dataset argument</p>
<ol>
<li><code>dataset.file</code>: <code>file</code> is an HTML5 file object. This is opened and parsed with the CSV parser.</li>
<li><code>dataset.data</code>: <code>data</code> is a string in CSV format. This is passed directly to the CSV parser</li>
<li><code>dataset.url</code>: a url to an online CSV file that is ajax accessible (note this usually requires either local or on a server that is CORS enabled). The file is then loaded using jQuery.ajax and parsed using the CSV parser (NB: this requires jQuery)</li>
</ol>
<p>All options generates similar data and use the memory store outcome, that is they return something like:</p>
<pre>
{
records: [ [...], [...], ... ],
metadata: { may be some metadata e.g. file name }
useMemoryStore: true
}
</pre> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">fetch</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dataset</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Deferred</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">file</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">reader</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FileReader</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">encoding</span> <span class="o">=</span> <span class="nx">dataset</span><span class="p">.</span><span class="nx">encoding</span> <span class="o">||</span> <span class="s1">&#39;UTF-8&#39;</span><span class="p">;</span>
<span class="nx">reader</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="nx">my</span><span class="p">.</span><span class="nx">extractFields</span><span class="p">(</span><span class="nx">my</span><span class="p">.</span><span class="nx">parseCSV</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">result</span><span class="p">,</span> <span class="nx">dataset</span><span class="p">),</span> <span class="nx">dataset</span><span class="p">);</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">useMemoryStore</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">metadata</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">filename</span><span class="o">:</span> <span class="nx">dataset</span><span class="p">.</span><span class="nx">file</span><span class="p">.</span><span class="nx">name</span>
<span class="p">}</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">out</span><span class="p">);</span>
<span class="p">};</span>
<span class="nx">reader</span><span class="p">.</span><span class="nx">onerror</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;Failed to load file. Code: &#39;</span> <span class="o">+</span> <span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span><span class="p">);</span>
<span class="p">};</span>
<span class="nx">reader</span><span class="p">.</span><span class="nx">readAsText</span><span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">file</span><span class="p">,</span> <span class="nx">encoding</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="nx">my</span><span class="p">.</span><span class="nx">extractFields</span><span class="p">(</span><span class="nx">my</span><span class="p">.</span><span class="nx">parseCSV</span><span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">data</span><span class="p">,</span> <span class="nx">dataset</span><span class="p">),</span> <span class="nx">dataset</span><span class="p">);</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">useMemoryStore</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">out</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">jQuery</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">url</span><span class="p">).</span><span class="nx">done</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="nx">my</span><span class="p">.</span><span class="nx">extractFields</span><span class="p">(</span><span class="nx">my</span><span class="p">.</span><span class="nx">parseCSV</span><span class="p">(</span><span class="nx">data</span><span class="p">,</span> <span class="nx">dataset</span><span class="p">),</span> <span class="nx">dataset</span><span class="p">);</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">useMemoryStore</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">out</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Convert array of rows in { records: [ ...] , fields: [ ... ] }
@param {Boolean} noHeaderRow If true assume that first row is not a header (i.e. list of fields but is data.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">extractFields</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">rows</span><span class="p">,</span> <span class="nx">noFields</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">noFields</span><span class="p">.</span><span class="nx">noHeaderRow</span> <span class="o">!==</span> <span class="kc">true</span> <span class="o">&amp;&amp;</span> <span class="nx">rows</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">{</span>
<span class="nx">fields</span><span class="o">:</span> <span class="nx">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="nx">records</span><span class="o">:</span> <span class="nx">rows</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">{</span>
<span class="nx">records</span><span class="o">:</span> <span class="nx">rows</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <h2>parseCSV</h2>
<p>Converts a Comma Separated Values string into an array of arrays.
Each line in the CSV becomes an array.</p>
<p>Empty fields are converted to nulls and non-quoted numbers are converted to integers or floats.</p>
<p>@return The CSV parsed as an array
@type Array</p>
<p>@param {String} s The string to convert
@param {Object} options Options for loading CSV including
@param {Boolean} [trim=false] If set to True leading and trailing
whitespace is stripped off of each non-quoted field as it is imported
@param {String} [delimiter=','] A one-character string used to separate
fields. It defaults to ','
@param {String} [quotechar='"'] A one-character string used to quote
fields containing special characters, such as the delimiter or
quotechar, or which contain new-line characters. It defaults to '"'</p>
<p>@param {Integer} skipInitialRows A integer number of rows to skip (default 0)</p>
<p>Heavily based on uselesscode's JS CSV parser (MIT Licensed):
http://www.uselesscode.org/javascript/csv/</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">parseCSV</span><span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">s</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Get rid of any trailing \n</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">s</span> <span class="o">=</span> <span class="nx">chomp</span><span class="p">(</span><span class="nx">s</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="nx">options</span> <span class="o">||</span> <span class="p">{};</span>
<span class="kd">var</span> <span class="nx">trm</span> <span class="o">=</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">trim</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="o">?</span> <span class="kc">false</span> <span class="o">:</span> <span class="kc">true</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">delimiter</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">delimiter</span> <span class="o">||</span> <span class="s1">&#39;,&#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">quotechar</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">quotechar</span> <span class="o">||</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">cur</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="c1">// The character we are currently processing.</span>
<span class="nx">inQuote</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">fieldQuoted</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">field</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="c1">// Buffer for building up the current field</span>
<span class="nx">row</span> <span class="o">=</span> <span class="p">[],</span>
<span class="nx">out</span> <span class="o">=</span> <span class="p">[],</span>
<span class="nx">i</span><span class="p">,</span>
<span class="nx">processField</span><span class="p">;</span>
<span class="nx">processField</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">field</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">fieldQuoted</span> <span class="o">!==</span> <span class="kc">true</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>If field is empty set to null</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">field</span> <span class="o">===</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">field</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>If the field was not quoted and we are trimming fields, trim it</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">trm</span> <span class="o">===</span> <span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">field</span> <span class="o">=</span> <span class="nx">trim</span><span class="p">(</span><span class="nx">field</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Convert unquoted numbers to their appropriate types</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">rxIsInt</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">field</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">field</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">field</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">rxIsFloat</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">field</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">field</span> <span class="o">=</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">field</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">field</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">s</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">cur</span> <span class="o">=</span> <span class="nx">s</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>If we are at a EOF or EOR</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">inQuote</span> <span class="o">===</span> <span class="kc">false</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">cur</span> <span class="o">===</span> <span class="nx">delimiter</span> <span class="o">||</span> <span class="nx">cur</span> <span class="o">===</span> <span class="s2">&quot;\n&quot;</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">field</span> <span class="o">=</span> <span class="nx">processField</span><span class="p">(</span><span class="nx">field</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Add the current field to the current row</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">row</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">field</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>If this is EOR append row to output and flush row</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">cur</span> <span class="o">===</span> <span class="s2">&quot;\n&quot;</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">row</span><span class="p">);</span>
<span class="nx">row</span> <span class="o">=</span> <span class="p">[];</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Flush the field buffer</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">field</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="nx">fieldQuoted</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>If it's not a quotechar, add it to the field buffer</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">cur</span> <span class="o">!==</span> <span class="nx">quotechar</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">field</span> <span class="o">+=</span> <span class="nx">cur</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">inQuote</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>We are not in a quote, start a quote</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">inQuote</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">fieldQuoted</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Next char is quotechar, this is an escaped quotechar</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">s</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">===</span> <span class="nx">quotechar</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">field</span> <span class="o">+=</span> <span class="nx">quotechar</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>Skip the next char</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">i</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>It's not escaping, so end quote</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">inQuote</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Add the last field</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">field</span> <span class="o">=</span> <span class="nx">processField</span><span class="p">(</span><span class="nx">field</span><span class="p">);</span>
<span class="nx">row</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">field</span><span class="p">);</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">row</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>Expose the ability to discard initial rows</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">skipInitialRows</span><span class="p">)</span> <span class="nx">out</span> <span class="o">=</span> <span class="nx">out</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">skipInitialRows</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">out</span><span class="p">;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <h2>serializeCSV</h2>
<p>Convert an Object or a simple array of arrays into a Comma
Separated Values string.</p>
<p>Nulls are converted to empty fields and integers or floats are converted to non-quoted numbers.</p>
<p>@return The array serialized as a CSV
@type String</p>
<p>@param {Object or Array} dataToSerialize The Object or array of arrays to convert. Object structure must be as follows:</p>
<pre><code>{
fields: [ {id: .., ...}, {id: ...,
records: [ { record }, { record }, ... ]
... // more attributes we do not care about
}
</code></pre>
<p>@param {object} options Options for serializing the CSV file including
delimiter and quotechar (see parseCSV options parameter above for
details on these).</p>
<p>Heavily based on uselesscode's JS CSV serializer (MIT Licensed):
http://www.uselesscode.org/javascript/csv/</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">serializeCSV</span><span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dataToSerialize</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">dataToSerialize</span> <span class="k">instanceof</span> <span class="nb">Array</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">a</span> <span class="o">=</span> <span class="nx">dataToSerialize</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">a</span> <span class="o">=</span> <span class="p">[];</span>
<span class="kd">var</span> <span class="nx">fieldNames</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">pluck</span><span class="p">(</span><span class="nx">dataToSerialize</span><span class="p">.</span><span class="nx">fields</span><span class="p">,</span> <span class="s1">&#39;id&#39;</span><span class="p">);</span>
<span class="nx">a</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">fieldNames</span><span class="p">);</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">dataToSerialize</span><span class="p">.</span><span class="nx">records</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">record</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">tmp</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">fieldNames</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">fn</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">record</span><span class="p">[</span><span class="nx">fn</span><span class="p">];</span>
<span class="p">});</span>
<span class="nx">a</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">tmp</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="nx">options</span> <span class="o">||</span> <span class="p">{};</span>
<span class="kd">var</span> <span class="nx">delimiter</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">delimiter</span> <span class="o">||</span> <span class="s1">&#39;,&#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">quotechar</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">quotechar</span> <span class="o">||</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">cur</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="c1">// The character we are currently processing.</span>
<span class="nx">field</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="c1">// Buffer for building up the current field</span>
<span class="nx">row</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
<span class="nx">out</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
<span class="nx">i</span><span class="p">,</span>
<span class="nx">j</span><span class="p">,</span>
<span class="nx">processField</span><span class="p">;</span>
<span class="nx">processField</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">field</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">field</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>If field is null set to empty string</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">field</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">field</span> <span class="o">===</span> <span class="s2">&quot;string&quot;</span> <span class="o">&amp;&amp;</span> <span class="nx">rxNeedsQuoting</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">field</span><span class="p">))</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>Convert string to delimited string</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">field</span> <span class="o">=</span> <span class="nx">quotechar</span> <span class="o">+</span> <span class="nx">field</span> <span class="o">+</span> <span class="nx">quotechar</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">field</span> <span class="o">===</span> <span class="s2">&quot;number&quot;</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>Convert number to string</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">field</span> <span class="o">=</span> <span class="nx">field</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">field</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">a</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">cur</span> <span class="o">=</span> <span class="nx">a</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="k">for</span> <span class="p">(</span><span class="nx">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;</span> <span class="nx">cur</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">j</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">field</span> <span class="o">=</span> <span class="nx">processField</span><span class="p">(</span><span class="nx">cur</span><span class="p">[</span><span class="nx">j</span><span class="p">]);</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>If this is EOR append row to output and flush row</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">j</span> <span class="o">===</span> <span class="p">(</span><span class="nx">cur</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">row</span> <span class="o">+=</span> <span class="nx">field</span><span class="p">;</span>
<span class="nx">out</span> <span class="o">+=</span> <span class="nx">row</span> <span class="o">+</span> <span class="s2">&quot;\n&quot;</span><span class="p">;</span>
<span class="nx">row</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>Add the current field to the current row</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">row</span> <span class="o">+=</span> <span class="nx">field</span> <span class="o">+</span> <span class="nx">delimiter</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>Flush the field buffer</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">field</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">out</span><span class="p">;</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">rxIsInt</span> <span class="o">=</span> <span class="sr">/^\d+$/</span><span class="p">,</span>
<span class="nx">rxIsFloat</span> <span class="o">=</span> <span class="sr">/^\d*\.\d+$|^\d+\.\d*$/</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>If a string has leading or trailing space,
contains a comma double quote or a newline
it needs to be quoted in CSV output</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">rxNeedsQuoting</span> <span class="o">=</span> <span class="sr">/^\s|\s$|,|&quot;|\n/</span><span class="p">,</span>
<span class="nx">trim</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>Fx 3.1 has a native trim function, it's about 10x faster, use it if it exists</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">trim</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">s</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">s</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
<span class="p">};</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">s</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">s</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/^\s*/</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\s*$/</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">);</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="p">}());</span>
<span class="kd">function</span> <span class="nx">chomp</span><span class="p">(</span><span class="nx">s</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">s</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">s</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">!==</span> <span class="s2">&quot;\n&quot;</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>Does not end with \n, just return string</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">s</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>Remove the \n</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">s</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">s</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}(</span><span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">CSV</span><span class="p">));</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -1,271 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>backend.dataproxy.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>backend.dataproxy.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.Backend = <span class="hljs-keyword">this</span>.recline.Backend || {};
<span class="hljs-keyword">this</span>.recline.Backend.DataProxy = <span class="hljs-keyword">this</span>.recline.Backend.DataProxy || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;
my.__type__ = <span class="hljs-string">'dataproxy'</span>;</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>URL for the dataproxy</p>
</div>
<div class="content"><div class='highlight'><pre> my.dataproxy_url = <span class="hljs-string">'//jsonpdataproxy.appspot.com'</span>;</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Timeout for dataproxy (after this time if no response we error)
Needed because use JSONP so do not receive e.g. 500 errors </p>
</div>
<div class="content"><div class='highlight'><pre> my.timeout = <span class="hljs-number">5000</span>;</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>use either jQuery or Underscore Deferred depending on what is available</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> Deferred = (<span class="hljs-keyword">typeof</span> jQuery !== <span class="hljs-string">"undefined"</span> &amp;&amp; jQuery.Deferred) || _.Deferred;</pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<h2 id="load">load</h2>
<p>Load data from a URL via the <a href="http://github.com/okfn/dataproxy">DataProxy</a>.</p>
<p>Returns array of field names and array of arrays for records</p>
</div>
<div class="content"><div class='highlight'><pre> my.fetch = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(dataset)</span> </span>{
<span class="hljs-keyword">var</span> data = {
url: dataset.url,
<span class="hljs-string">'max-results'</span>: dataset.size || dataset.rows || <span class="hljs-number">1000</span>,
type: dataset.format || <span class="hljs-string">''</span>
};
<span class="hljs-keyword">var</span> jqxhr = jQuery.ajax({
url: my.dataproxy_url,
data: data,
dataType: <span class="hljs-string">'jsonp'</span>
});
<span class="hljs-keyword">var</span> dfd = <span class="hljs-keyword">new</span> Deferred();
_wrapInTimeout(jqxhr).done(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(results)</span> </span>{
<span class="hljs-keyword">if</span> (results.error) {
dfd.reject(results.error);
}
dfd.resolve({
records: results.data,
fields: results.fields,
useMemoryStore: <span class="hljs-literal">true</span>
});
})
.fail(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(args)</span> </span>{
dfd.reject(args);
});
<span class="hljs-keyword">return</span> dfd.promise();
};</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<h2 id="_wrapintimeout">_wrapInTimeout</h2>
<p>Convenience method providing a crude way to catch backend errors on JSONP calls.
Many of backends use JSONP and so will not get error messages and this is
a crude way to catch those errors.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> _wrapInTimeout = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(ourFunction)</span> </span>{
<span class="hljs-keyword">var</span> dfd = <span class="hljs-keyword">new</span> Deferred();
<span class="hljs-keyword">var</span> timer = setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
dfd.reject({
message: <span class="hljs-string">'Request Error: Backend did not respond after '</span> + (my.timeout / <span class="hljs-number">1000</span>) + <span class="hljs-string">' seconds'</span>
});
}, my.timeout);
ourFunction.done(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(args)</span> </span>{
clearTimeout(timer);
dfd.resolve(args);
})
.fail(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(args)</span> </span>{
clearTimeout(timer);
dfd.reject(args);
})
;
<span class="hljs-keyword">return</span> dfd.promise();
};
}(<span class="hljs-keyword">this</span>.recline.Backend.DataProxy));</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,242 +0,0 @@
<!DOCTYPE html> <html> <head> <title>backend.elasticsearch.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="backend.csv.html"> backend.csv.js </a> <a class="source" href="backend.dataproxy.html"> backend.dataproxy.js </a> <a class="source" href="backend.elasticsearch.html"> backend.elasticsearch.js </a> <a class="source" href="backend.gdocs.html"> backend.gdocs.js </a> <a class="source" href="backend.memory.html"> backend.memory.js </a> <a class="source" href="ecma-fixes.html"> ecma-fixes.js </a> <a class="source" href="model.html"> model.js </a> <a class="source" href="view.flot.html"> view.flot.js </a> <a class="source" href="view.graph.html"> view.graph.js </a> <a class="source" href="view.grid.html"> view.grid.js </a> <a class="source" href="view.map.html"> view.map.js </a> <a class="source" href="view.multiview.html"> view.multiview.js </a> <a class="source" href="view.slickgrid.html"> view.slickgrid.js </a> <a class="source" href="view.timeline.html"> view.timeline.js </a> <a class="source" href="widget.facetviewer.html"> widget.facetviewer.js </a> <a class="source" href="widget.fields.html"> widget.fields.js </a> <a class="source" href="widget.filtereditor.html"> widget.filtereditor.js </a> <a class="source" href="widget.pager.html"> widget.pager.js </a> <a class="source" href="widget.queryeditor.html"> widget.queryeditor.js </a> <a class="source" href="widget.valuefilter.html"> widget.valuefilter.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> backend.elasticsearch.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">recline</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span> <span class="o">||</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span> <span class="o">||</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">ElasticSearch</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">ElasticSearch</span> <span class="o">||</span> <span class="p">{};</span>
<span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">my</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">my</span><span class="p">.</span><span class="nx">__type__</span> <span class="o">=</span> <span class="s1">&#39;elasticsearch&#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>use either jQuery or Underscore Deferred depending on what is available</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">Deferred</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">jQuery</span><span class="p">)</span> <span class="o">?</span> <span class="nx">_</span><span class="p">.</span><span class="nx">Deferred</span> <span class="o">:</span> <span class="nx">jQuery</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <h2>ElasticSearch Wrapper</h2>
<p>A simple JS wrapper around an <a href="http://www.elasticsearch.org/">ElasticSearch</a> endpoints.</p>
<p>@param {String} endpoint: url for ElasticSearch type/table, e.g. for ES running
on http://localhost:9200 with index twitter and type tweet it would be:</p>
<pre>http://localhost:9200/twitter/tweet</pre>
<p>@param {Object} options: set of options such as:</p>
<ul>
<li>headers - {dict of headers to add to each request}</li>
<li>dataType: dataType for AJAx requests e.g. set to jsonp to make jsonp requests (default is json requests)</li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">Wrapper</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">endpoint</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">endpoint</span> <span class="o">=</span> <span class="nx">endpoint</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">options</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">&#39;json&#39;</span>
<span class="p">},</span>
<span class="nx">options</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <h3>mapping</h3>
<p>Get ES mapping for this type/table</p>
<p>@return promise compatible deferred object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">mapping</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">schemaUrl</span> <span class="o">=</span> <span class="nx">self</span><span class="p">.</span><span class="nx">endpoint</span> <span class="o">+</span> <span class="s1">&#39;/_mapping&#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">jqxhr</span> <span class="o">=</span> <span class="nx">makeRequest</span><span class="p">({</span>
<span class="nx">url</span><span class="o">:</span> <span class="nx">schemaUrl</span><span class="p">,</span>
<span class="nx">dataType</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">dataType</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">jqxhr</span><span class="p">;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <h3>get</h3>
<p>Get record corresponding to specified id</p>
<p>@return promise compatible deferred object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">get</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">base</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">endpoint</span> <span class="o">+</span> <span class="s1">&#39;/&#39;</span> <span class="o">+</span> <span class="nx">id</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">makeRequest</span><span class="p">({</span>
<span class="nx">url</span><span class="o">:</span> <span class="nx">base</span><span class="p">,</span>
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">&#39;json&#39;</span>
<span class="p">});</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <h3>upsert</h3>
<p>create / update a record to ElasticSearch backend</p>
<p>@param {Object} doc an object to insert to the index.
@return deferred supporting promise API</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">upsert</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">doc</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">doc</span><span class="p">);</span>
<span class="nx">url</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">endpoint</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">doc</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">url</span> <span class="o">+=</span> <span class="s1">&#39;/&#39;</span> <span class="o">+</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">makeRequest</span><span class="p">({</span>
<span class="nx">url</span><span class="o">:</span> <span class="nx">url</span><span class="p">,</span>
<span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
<span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">,</span>
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">&#39;json&#39;</span>
<span class="p">});</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <h3>delete</h3>
<p>Delete a record from the ElasticSearch backend.</p>
<p>@param {Object} id id of object to delete
@return deferred supporting promise API</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">remove</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">url</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">endpoint</span><span class="p">;</span>
<span class="nx">url</span> <span class="o">+=</span> <span class="s1">&#39;/&#39;</span> <span class="o">+</span> <span class="nx">id</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">makeRequest</span><span class="p">({</span>
<span class="nx">url</span><span class="o">:</span> <span class="nx">url</span><span class="p">,</span>
<span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">,</span>
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">&#39;json&#39;</span>
<span class="p">});</span>
<span class="p">};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_normalizeQuery</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">queryObj</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">queryInfo</span> <span class="o">=</span> <span class="p">(</span><span class="nx">queryObj</span> <span class="o">&amp;&amp;</span> <span class="nx">queryObj</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">)</span> <span class="o">?</span> <span class="nx">queryObj</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">()</span> <span class="o">:</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">({},</span> <span class="nx">queryObj</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">constant_score</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">query</span><span class="o">:</span> <span class="p">{}</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">queryInfo</span><span class="p">.</span><span class="nx">q</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">constant_score</span><span class="p">.</span><span class="nx">query</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">match_all</span><span class="o">:</span> <span class="p">{}</span>
<span class="p">};</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">constant_score</span><span class="p">.</span><span class="nx">query</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">query_string</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">query</span><span class="o">:</span> <span class="nx">queryInfo</span><span class="p">.</span><span class="nx">q</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">queryInfo</span><span class="p">.</span><span class="nx">filters</span> <span class="o">&amp;&amp;</span> <span class="nx">queryInfo</span><span class="p">.</span><span class="nx">filters</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">constant_score</span><span class="p">.</span><span class="nx">filter</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">and</span><span class="o">:</span> <span class="p">[]</span>
<span class="p">};</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">queryInfo</span><span class="p">.</span><span class="nx">filters</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">filter</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">constant_score</span><span class="p">.</span><span class="nx">filter</span><span class="p">.</span><span class="nx">and</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">self</span><span class="p">.</span><span class="nx">_convertFilter</span><span class="p">(</span><span class="nx">filter</span><span class="p">));</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">out</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>convert from Recline sort structure to ES form
http://www.elasticsearch.org/guide/reference/api/search/sort.html</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">_normalizeSort</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">sort</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">sort</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">sortObj</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">_tmp</span> <span class="o">=</span> <span class="p">{};</span>
<span class="kd">var</span> <span class="nx">_tmp2</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">clone</span><span class="p">(</span><span class="nx">sortObj</span><span class="p">);</span>
<span class="k">delete</span> <span class="nx">_tmp2</span><span class="p">[</span><span class="s1">&#39;field&#39;</span><span class="p">];</span>
<span class="nx">_tmp</span><span class="p">[</span><span class="nx">sortObj</span><span class="p">.</span><span class="nx">field</span><span class="p">]</span> <span class="o">=</span> <span class="nx">_tmp2</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">_tmp</span><span class="p">;</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">out</span><span class="p">;</span>
<span class="p">},</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_convertFilter</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">filter</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">out</span><span class="p">[</span><span class="nx">filter</span><span class="p">.</span><span class="nx">type</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">filter</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;term&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">term</span><span class="p">[</span><span class="nx">filter</span><span class="p">.</span><span class="nx">field</span><span class="p">]</span> <span class="o">=</span> <span class="nx">filter</span><span class="p">.</span><span class="nx">term</span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">();</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">filter</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;geo_distance&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">geo_distance</span><span class="p">[</span><span class="nx">filter</span><span class="p">.</span><span class="nx">field</span><span class="p">]</span> <span class="o">=</span> <span class="nx">filter</span><span class="p">.</span><span class="nx">point</span><span class="p">;</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">geo_distance</span><span class="p">.</span><span class="nx">distance</span> <span class="o">=</span> <span class="nx">filter</span><span class="p">.</span><span class="nx">distance</span><span class="p">;</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">geo_distance</span><span class="p">.</span><span class="nx">unit</span> <span class="o">=</span> <span class="nx">filter</span><span class="p">.</span><span class="nx">unit</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">out</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <h3>query</h3>
<p>@return deferred supporting promise API</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">query</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">queryObj</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">esQuery</span> <span class="o">=</span> <span class="p">(</span><span class="nx">queryObj</span> <span class="o">&amp;&amp;</span> <span class="nx">queryObj</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">)</span> <span class="o">?</span> <span class="nx">queryObj</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">()</span> <span class="o">:</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">({},</span> <span class="nx">queryObj</span><span class="p">);</span>
<span class="nx">esQuery</span><span class="p">.</span><span class="nx">query</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_normalizeQuery</span><span class="p">(</span><span class="nx">queryObj</span><span class="p">);</span>
<span class="k">delete</span> <span class="nx">esQuery</span><span class="p">.</span><span class="nx">q</span><span class="p">;</span>
<span class="k">delete</span> <span class="nx">esQuery</span><span class="p">.</span><span class="nx">filters</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">esQuery</span><span class="p">.</span><span class="nx">sort</span> <span class="o">&amp;&amp;</span> <span class="nx">esQuery</span><span class="p">.</span><span class="nx">sort</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">esQuery</span><span class="p">.</span><span class="nx">sort</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_normalizeSort</span><span class="p">(</span><span class="nx">esQuery</span><span class="p">.</span><span class="nx">sort</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">{</span><span class="nx">source</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">esQuery</span><span class="p">)};</span>
<span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">endpoint</span> <span class="o">+</span> <span class="s1">&#39;/_search&#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">jqxhr</span> <span class="o">=</span> <span class="nx">makeRequest</span><span class="p">({</span>
<span class="nx">url</span><span class="o">:</span> <span class="nx">url</span><span class="p">,</span>
<span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">,</span>
<span class="nx">dataType</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">dataType</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">jqxhr</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <h2>Recline Connectors</h2>
<p>Requires URL of ElasticSearch endpoint to be specified on the dataset
via the url attribute.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>ES options which are passed through to <code>options</code> on Wrapper (see Wrapper for details)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">esOptions</span> <span class="o">=</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <h3>fetch</h3> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">fetch</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dataset</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">es</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">my</span><span class="p">.</span><span class="nx">Wrapper</span><span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">my</span><span class="p">.</span><span class="nx">esOptions</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Deferred</span><span class="p">();</span>
<span class="nx">es</span><span class="p">.</span><span class="nx">mapping</span><span class="p">().</span><span class="nx">done</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">schema</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">schema</span><span class="p">){</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">reject</span><span class="p">({</span><span class="s1">&#39;message&#39;</span><span class="o">:</span><span class="s1">&#39;Elastic Search did not return a mapping&#39;</span><span class="p">});</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>only one top level key in ES = the type so we can ignore it</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">schema</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">fieldData</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">schema</span><span class="p">[</span><span class="nx">key</span><span class="p">].</span><span class="nx">properties</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dict</span><span class="p">,</span> <span class="nx">fieldName</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">dict</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">fieldName</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">dict</span><span class="p">;</span>
<span class="p">});</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">({</span>
<span class="nx">fields</span><span class="o">:</span> <span class="nx">fieldData</span>
<span class="p">});</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">fail</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">arguments</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <h3>save</h3> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">save</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">changes</span><span class="p">,</span> <span class="nx">dataset</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">es</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">my</span><span class="p">.</span><span class="nx">Wrapper</span><span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">my</span><span class="p">.</span><span class="nx">esOptions</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">changes</span><span class="p">.</span><span class="nx">creates</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="nx">changes</span><span class="p">.</span><span class="nx">updates</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="nx">changes</span><span class="p">.</span><span class="nx">deletes</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Deferred</span><span class="p">();</span>
<span class="nx">msg</span> <span class="o">=</span> <span class="s1">&#39;Saving more than one item at a time not yet supported&#39;</span><span class="p">;</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">changes</span><span class="p">.</span><span class="nx">creates</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">es</span><span class="p">.</span><span class="nx">upsert</span><span class="p">(</span><span class="nx">changes</span><span class="p">.</span><span class="nx">creates</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">changes</span><span class="p">.</span><span class="nx">updates</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">es</span><span class="p">.</span><span class="nx">upsert</span><span class="p">(</span><span class="nx">changes</span><span class="p">.</span><span class="nx">updates</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">changes</span><span class="p">.</span><span class="nx">deletes</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">es</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">changes</span><span class="p">.</span><span class="nx">deletes</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">id</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <h3>query</h3> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">query</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">queryObj</span><span class="p">,</span> <span class="nx">dataset</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Deferred</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">es</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">my</span><span class="p">.</span><span class="nx">Wrapper</span><span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">my</span><span class="p">.</span><span class="nx">esOptions</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">jqxhr</span> <span class="o">=</span> <span class="nx">es</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span><span class="nx">queryObj</span><span class="p">);</span>
<span class="nx">jqxhr</span><span class="p">.</span><span class="nx">done</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">results</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">total</span><span class="o">:</span> <span class="nx">results</span><span class="p">.</span><span class="nx">hits</span><span class="p">.</span><span class="nx">total</span>
<span class="p">};</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">hits</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">results</span><span class="p">.</span><span class="nx">hits</span><span class="p">.</span><span class="nx">hits</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">hit</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="s1">&#39;id&#39;</span> <span class="k">in</span> <span class="nx">hit</span><span class="p">.</span><span class="nx">_source</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">hit</span><span class="p">.</span><span class="nx">_id</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">hit</span><span class="p">.</span><span class="nx">_source</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">hit</span><span class="p">.</span><span class="nx">_id</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">hit</span><span class="p">.</span><span class="nx">_source</span><span class="p">;</span>
<span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">results</span><span class="p">.</span><span class="nx">facets</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">out</span><span class="p">.</span><span class="nx">facets</span> <span class="o">=</span> <span class="nx">results</span><span class="p">.</span><span class="nx">facets</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">out</span><span class="p">);</span>
<span class="p">}).</span><span class="nx">fail</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">errorObj</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Failed: &#39;</span> <span class="o">+</span> <span class="nx">errorObj</span><span class="p">.</span><span class="nx">status</span> <span class="o">+</span> <span class="s1">&#39; code&#39;</span><span class="p">,</span>
<span class="nx">message</span><span class="o">:</span> <span class="nx">errorObj</span><span class="p">.</span><span class="nx">responseText</span>
<span class="p">};</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="nx">out</span><span class="p">);</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <h3>makeRequest</h3>
<p>Just $.ajax but in any headers in the 'headers' attribute of this
Backend instance. Example:</p>
<pre>
var jqxhr = this._makeRequest({
url: the-url
});
</pre> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">makeRequest</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">,</span> <span class="nx">headers</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">extras</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">headers</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">extras</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">beforeSend</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">headers</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">req</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">extras</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
<span class="p">};</span>
<span class="p">}(</span><span class="nx">jQuery</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">ElasticSearch</span><span class="p">));</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -1,137 +0,0 @@
<!DOCTYPE html> <html> <head> <title>backend.gdocs.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="backend.csv.html"> backend.csv.js </a> <a class="source" href="backend.dataproxy.html"> backend.dataproxy.js </a> <a class="source" href="backend.elasticsearch.html"> backend.elasticsearch.js </a> <a class="source" href="backend.gdocs.html"> backend.gdocs.js </a> <a class="source" href="backend.memory.html"> backend.memory.js </a> <a class="source" href="ecma-fixes.html"> ecma-fixes.js </a> <a class="source" href="model.html"> model.js </a> <a class="source" href="view.flot.html"> view.flot.js </a> <a class="source" href="view.graph.html"> view.graph.js </a> <a class="source" href="view.grid.html"> view.grid.js </a> <a class="source" href="view.map.html"> view.map.js </a> <a class="source" href="view.multiview.html"> view.multiview.js </a> <a class="source" href="view.slickgrid.html"> view.slickgrid.js </a> <a class="source" href="view.timeline.html"> view.timeline.js </a> <a class="source" href="widget.facetviewer.html"> widget.facetviewer.js </a> <a class="source" href="widget.fields.html"> widget.fields.js </a> <a class="source" href="widget.filtereditor.html"> widget.filtereditor.js </a> <a class="source" href="widget.pager.html"> widget.pager.js </a> <a class="source" href="widget.queryeditor.html"> widget.queryeditor.js </a> <a class="source" href="widget.valuefilter.html"> widget.valuefilter.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> backend.gdocs.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">recline</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span> <span class="o">||</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span> <span class="o">||</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">GDocs</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">GDocs</span> <span class="o">||</span> <span class="p">{};</span>
<span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">my</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">my</span><span class="p">.</span><span class="nx">__type__</span> <span class="o">=</span> <span class="s1">&#39;gdocs&#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>use either jQuery or Underscore Deferred depending on what is available</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">Deferred</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">jQuery</span><span class="p">)</span> <span class="o">?</span> <span class="nx">_</span><span class="p">.</span><span class="nx">Deferred</span> <span class="o">:</span> <span class="nx">jQuery</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <h2>Google spreadsheet backend</h2>
<p>Fetch data from a Google Docs spreadsheet.</p>
<p>Dataset must have a url attribute pointing to the Gdocs or its JSON feed e.g.</p>
<pre>
var dataset = new recline.Model.Dataset({
url: 'https://docs.google.com/spreadsheet/ccc?key=0Aon3JiuouxLUdGlQVDJnbjZRSU1tUUJWOUZXRG53VkE#gid=0'
},
'gdocs'
);
var dataset = new recline.Model.Dataset({
url: 'https://spreadsheets.google.com/feeds/list/0Aon3JiuouxLUdDQwZE1JdV94cUd6NWtuZ0IyWTBjLWc/od6/public/values?alt=json'
},
'gdocs'
);
</pre>
<p>@return object with two attributes</p>
<ul>
<li>fields: array of Field objects</li>
<li>records: array of objects for each row</li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">fetch</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dataset</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Deferred</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">urls</span> <span class="o">=</span> <span class="nx">my</span><span class="p">.</span><span class="nx">getGDocsAPIUrls</span><span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">url</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>TODO cover it with tests
get the spreadsheet title</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">titleDfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Deferred</span><span class="p">();</span>
<span class="nx">jQuery</span><span class="p">.</span><span class="nx">getJSON</span><span class="p">(</span><span class="nx">urls</span><span class="p">.</span><span class="nx">spreadsheet</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">titleDfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">({</span>
<span class="nx">spreadsheetTitle</span><span class="o">:</span> <span class="nx">d</span><span class="p">.</span><span class="nx">feed</span><span class="p">.</span><span class="nx">title</span><span class="p">.</span><span class="nx">$t</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">titleDfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span>
<span class="p">}()).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>get the actual worksheet data</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">jQuery</span><span class="p">.</span><span class="nx">getJSON</span><span class="p">(</span><span class="nx">urls</span><span class="p">.</span><span class="nx">worksheet</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">my</span><span class="p">.</span><span class="nx">parseData</span><span class="p">(</span><span class="nx">d</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">fields</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">fields</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">fieldId</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">{</span><span class="nx">id</span><span class="o">:</span> <span class="nx">fieldId</span><span class="p">};</span>
<span class="p">});</span>
<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">({</span>
<span class="nx">metadata</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">title</span><span class="o">:</span> <span class="nx">response</span><span class="p">.</span><span class="nx">spreadsheetTitle</span> <span class="o">+</span><span class="s2">&quot; :: &quot;</span><span class="o">+</span> <span class="nx">result</span><span class="p">.</span><span class="nx">worksheetTitle</span><span class="p">,</span>
<span class="nx">spreadsheetTitle</span><span class="o">:</span> <span class="nx">response</span><span class="p">.</span><span class="nx">spreadsheetTitle</span><span class="p">,</span>
<span class="nx">worksheetTitle</span> <span class="o">:</span> <span class="nx">result</span><span class="p">.</span><span class="nx">worksheetTitle</span>
<span class="p">},</span>
<span class="nx">records</span> <span class="o">:</span> <span class="nx">result</span><span class="p">.</span><span class="nx">records</span><span class="p">,</span>
<span class="nx">fields</span> <span class="o">:</span> <span class="nx">fields</span><span class="p">,</span>
<span class="nx">useMemoryStore</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <h2>parseData</h2>
<p>Parse data from Google Docs API into a reasonable form</p>
<p>:options: (optional) optional argument dictionary:
columnsToUse: list of columns to use (specified by field names)
colTypes: dictionary (with column names as keys) specifying types (e.g. range, percent for use in conversion).
:return: tabular data object (hash with keys: field and data).</p>
<p>Issues: seems google docs return columns in rows in random order and not even sure whether consistent across rows.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">parseData</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">gdocsSpreadsheet</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="nx">options</span> <span class="o">||</span> <span class="p">{};</span>
<span class="kd">var</span> <span class="nx">colTypes</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">colTypes</span> <span class="o">||</span> <span class="p">{};</span>
<span class="kd">var</span> <span class="nx">results</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">fields</span> <span class="o">:</span> <span class="p">[],</span>
<span class="nx">records</span><span class="o">:</span> <span class="p">[]</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">entries</span> <span class="o">=</span> <span class="nx">gdocsSpreadsheet</span><span class="p">.</span><span class="nx">feed</span><span class="p">.</span><span class="nx">entry</span> <span class="o">||</span> <span class="p">[];</span>
<span class="kd">var</span> <span class="nx">key</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">colName</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>percentage values (e.g. 23.3%)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">rep</span> <span class="o">=</span> <span class="sr">/^([\d\.\-]+)\%$/</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="nx">key</span> <span class="k">in</span> <span class="nx">entries</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>it's barely possible it has inherited keys starting with 'gsx$'</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="sr">/^gsx/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">colName</span> <span class="o">=</span> <span class="nx">key</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>
<span class="nx">results</span><span class="p">.</span><span class="nx">fields</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">colName</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>converts non numberical values that should be numerical (22.3%[string] -> 0.223[float])</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">results</span><span class="p">.</span><span class="nx">records</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">entries</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">entry</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">row</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">results</span><span class="p">.</span><span class="nx">fields</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">col</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">_keyname</span> <span class="o">=</span> <span class="s1">&#39;gsx$&#39;</span> <span class="o">+</span> <span class="nx">col</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">entry</span><span class="p">[</span><span class="nx">_keyname</span><span class="p">].</span><span class="nx">$t</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">num</span><span class="p">;</span>
</pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>TODO cover this part of code with test
TODO use the regexp only once
if labelled as % and value contains %, convert</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="nx">colTypes</span><span class="p">[</span><span class="nx">col</span><span class="p">]</span> <span class="o">===</span> <span class="s1">&#39;percent&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">rep</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">value</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">num</span> <span class="o">=</span> <span class="nx">rep</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">value</span><span class="p">)[</span><span class="mi">1</span><span class="p">];</span>
<span class="nx">value</span> <span class="o">=</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">num</span><span class="p">)</span> <span class="o">/</span> <span class="mi">100</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">row</span><span class="p">[</span><span class="nx">col</span><span class="p">]</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">row</span><span class="p">;</span>
<span class="p">});</span>
<span class="nx">results</span><span class="p">.</span><span class="nx">worksheetTitle</span> <span class="o">=</span> <span class="nx">gdocsSpreadsheet</span><span class="p">.</span><span class="nx">feed</span><span class="p">.</span><span class="nx">title</span><span class="p">.</span><span class="nx">$t</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Convenience function to get GDocs JSON API Url from standard URL</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">my</span><span class="p">.</span><span class="nx">getGDocsAPIUrls</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>https://docs.google.com/spreadsheet/ccc?key=XXXX#gid=YYY</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">regex</span> <span class="o">=</span> <span class="sr">/.*spreadsheet\/ccc?.*key=([^#?&amp;+]+)[^#]*(#gid=([\d]+).*)?/</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">matches</span> <span class="o">=</span> <span class="nx">url</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">regex</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">key</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">worksheet</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">urls</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="o">!!</span><span class="nx">matches</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">key</span> <span class="o">=</span> <span class="nx">matches</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>the gid in url is 0-based and feed url is 1-based</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">worksheet</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">matches</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isNaN</span><span class="p">(</span><span class="nx">worksheet</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">worksheet</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">urls</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">worksheet</span> <span class="o">:</span> <span class="s1">&#39;https://spreadsheets.google.com/feeds/list/&#39;</span><span class="o">+</span> <span class="nx">key</span> <span class="o">+</span><span class="s1">&#39;/&#39;</span><span class="o">+</span> <span class="nx">worksheet</span> <span class="o">+</span><span class="s1">&#39;/public/values?alt=json&#39;</span><span class="p">,</span>
<span class="nx">spreadsheet</span><span class="o">:</span> <span class="s1">&#39;https://spreadsheets.google.com/feeds/worksheets/&#39;</span><span class="o">+</span> <span class="nx">key</span> <span class="o">+</span><span class="s1">&#39;/public/basic?alt=json&#39;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>we assume that it's one of the feeds urls</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">key</span> <span class="o">=</span> <span class="nx">url</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)[</span><span class="mi">5</span><span class="p">];</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>by default then, take first worksheet</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">worksheet</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="nx">urls</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">worksheet</span> <span class="o">:</span> <span class="s1">&#39;https://spreadsheets.google.com/feeds/list/&#39;</span><span class="o">+</span> <span class="nx">key</span> <span class="o">+</span><span class="s1">&#39;/&#39;</span><span class="o">+</span> <span class="nx">worksheet</span> <span class="o">+</span><span class="s1">&#39;/public/values?alt=json&#39;</span><span class="p">,</span>
<span class="nx">spreadsheet</span><span class="o">:</span> <span class="s1">&#39;https://spreadsheets.google.com/feeds/worksheets/&#39;</span><span class="o">+</span> <span class="nx">key</span> <span class="o">+</span><span class="s1">&#39;/public/basic?alt=json&#39;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">urls</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">}(</span><span class="k">this</span><span class="p">.</span><span class="nx">recline</span><span class="p">.</span><span class="nx">Backend</span><span class="p">.</span><span class="nx">GDocs</span><span class="p">));</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -1,631 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>backend.memory.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>backend.memory.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.Backend = <span class="hljs-keyword">this</span>.recline.Backend || {};
<span class="hljs-keyword">this</span>.recline.Backend.Memory = <span class="hljs-keyword">this</span>.recline.Backend.Memory || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;
my.__type__ = <span class="hljs-string">'memory'</span>;</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>private data - use either jQuery or Underscore Deferred depending on what is available</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> Deferred = (<span class="hljs-keyword">typeof</span> jQuery !== <span class="hljs-string">"undefined"</span> &amp;&amp; jQuery.Deferred) || _.Deferred;</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<h2 id="data-wrapper">Data Wrapper</h2>
<p>Turn a simple array of JS objects into a mini data-store with
functionality like querying, faceting, updating (by ID) and deleting (by
ID).</p>
<p>@param records list of hashes for each record/row in the data ({key:
value, key: value})
@param fields (optional) list of field hashes (each hash defining a field
as per recline.Model.Field). If fields not specified they will be taken
from the data.</p>
</div>
<div class="content"><div class='highlight'><pre> my.Store = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(records, fields)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">this</span>.records = records;</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>backwards compatability (in v0.5 records was named data)</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.data = <span class="hljs-keyword">this</span>.records;
<span class="hljs-keyword">if</span> (fields) {
<span class="hljs-keyword">this</span>.fields = fields;
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">if</span> (records) {
<span class="hljs-keyword">this</span>.fields = _.map(records[<span class="hljs-number">0</span>], <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(value, key)</span> </span>{
<span class="hljs-keyword">return</span> {id: key, type: <span class="hljs-string">'string'</span>};
});
}
}
<span class="hljs-keyword">this</span>.update = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span> </span>{
_.each(self.records, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(internalDoc, idx)</span> </span>{
<span class="hljs-keyword">if</span>(doc.id === internalDoc.id) {
self.records[idx] = doc;
}
});
};
<span class="hljs-keyword">this</span>.remove = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span> </span>{
<span class="hljs-keyword">var</span> newdocs = _.reject(self.records, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(internalDoc)</span> </span>{
<span class="hljs-keyword">return</span> (doc.id === internalDoc.id);
});
<span class="hljs-keyword">this</span>.records = newdocs;
};
<span class="hljs-keyword">this</span>.save = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(changes, dataset)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> dfd = <span class="hljs-keyword">new</span> Deferred();</pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>TODO _.each(changes.creates) { … }</p>
</div>
<div class="content"><div class='highlight'><pre> _.each(changes.updates, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(record)</span> </span>{
self.update(record);
});
_.each(changes.deletes, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(record)</span> </span>{
self.remove(record);
});
dfd.resolve();
<span class="hljs-keyword">return</span> dfd.promise();
},
<span class="hljs-keyword">this</span>.query = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(queryObj)</span> </span>{
<span class="hljs-keyword">var</span> dfd = <span class="hljs-keyword">new</span> Deferred();
<span class="hljs-keyword">var</span> numRows = queryObj.size || <span class="hljs-keyword">this</span>.records.length;
<span class="hljs-keyword">var</span> start = queryObj.from || <span class="hljs-number">0</span>;
<span class="hljs-keyword">var</span> results = <span class="hljs-keyword">this</span>.records;
results = <span class="hljs-keyword">this</span>._applyFilters(results, queryObj);
results = <span class="hljs-keyword">this</span>._applyFreeTextQuery(results, queryObj);</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>TODO: this is not complete sorting!
Whats wrong is we sort on the <em>last</em> entry in the sort list if there are multiple sort criteria</p>
</div>
<div class="content"><div class='highlight'><pre> _.each(queryObj.sort, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(sortObj)</span> </span>{
<span class="hljs-keyword">var</span> fieldName = sortObj.field;
results = _.sortBy(results, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span> </span>{
<span class="hljs-keyword">var</span> _out = doc[fieldName];
<span class="hljs-keyword">return</span> _out;
});
<span class="hljs-keyword">if</span> (sortObj.order == <span class="hljs-string">'desc'</span>) {
results.reverse();
}
});
<span class="hljs-keyword">var</span> facets = <span class="hljs-keyword">this</span>.computeFacets(results, queryObj);
<span class="hljs-keyword">var</span> out = {
total: results.length,
hits: results.slice(start, start+numRows),
facets: facets
};
dfd.resolve(out);
<span class="hljs-keyword">return</span> dfd.promise();
};</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>in place filtering</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>._applyFilters = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(results, queryObj)</span> </span>{
<span class="hljs-keyword">var</span> filters = queryObj.filters;</pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>register filters</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> filterFunctions = {
term : term,
terms : terms,
range : range,
geo_distance : geo_distance
};
<span class="hljs-keyword">var</span> dataParsers = {
integer: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{ <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseFloat</span>(e, <span class="hljs-number">10</span>); },
<span class="hljs-string">'float'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{ <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseFloat</span>(e, <span class="hljs-number">10</span>); },
number: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{ <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseFloat</span>(e, <span class="hljs-number">10</span>); },
string : <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{ <span class="hljs-keyword">return</span> e.toString(); },
date : <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{ <span class="hljs-keyword">return</span> moment(e).valueOf(); },
datetime : <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(e).valueOf(); }
};
<span class="hljs-keyword">var</span> keyedFields = {};
_.each(self.fields, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field)</span> </span>{
keyedFields[field.id] = field;
});
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getDataParser</span><span class="hljs-params">(filter)</span> </span>{
<span class="hljs-keyword">var</span> fieldType = keyedFields[filter.field].type || <span class="hljs-string">'string'</span>;
<span class="hljs-keyword">return</span> dataParsers[fieldType];
}</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>filter records</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> _.filter(results, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(record)</span> </span>{
<span class="hljs-keyword">var</span> passes = _.map(filters, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(filter)</span> </span>{
<span class="hljs-keyword">return</span> filterFunctions[filter.type](record, filter);
});</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>return only these records that pass all filters</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> _.all(passes, _.identity);
});</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>filters definitions</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">term</span><span class="hljs-params">(record, filter)</span> </span>{
<span class="hljs-keyword">var</span> parse = getDataParser(filter);
<span class="hljs-keyword">var</span> value = parse(record[filter.field]);
<span class="hljs-keyword">var</span> term = parse(filter.term);
<span class="hljs-keyword">return</span> (value === term);
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">terms</span><span class="hljs-params">(record, filter)</span> </span>{
<span class="hljs-keyword">var</span> parse = getDataParser(filter);
<span class="hljs-keyword">var</span> value = parse(record[filter.field]);
<span class="hljs-keyword">var</span> terms = parse(filter.terms).split(<span class="hljs-string">","</span>);
<span class="hljs-keyword">return</span> (_.indexOf(terms, value) &gt;= <span class="hljs-number">0</span>);
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">range</span><span class="hljs-params">(record, filter)</span> </span>{
<span class="hljs-keyword">var</span> fromnull = (_.isUndefined(filter.from) || filter.from === <span class="hljs-literal">null</span> || filter.from === <span class="hljs-string">''</span>);
<span class="hljs-keyword">var</span> tonull = (_.isUndefined(filter.to) || filter.to === <span class="hljs-literal">null</span> || filter.to === <span class="hljs-string">''</span>);
<span class="hljs-keyword">var</span> parse = getDataParser(filter);
<span class="hljs-keyword">var</span> value = parse(record[filter.field]);
<span class="hljs-keyword">var</span> from = parse(fromnull ? <span class="hljs-string">''</span> : filter.from);
<span class="hljs-keyword">var</span> to = parse(tonull ? <span class="hljs-string">''</span> : filter.to);</pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>if at least one end of range is set do not allow to get through
note that for strings &lt;= {any-character} e.g. &lt;= a</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ((!fromnull || !tonull) &amp;&amp; value === <span class="hljs-string">''</span>) {
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}
<span class="hljs-keyword">return</span> ((fromnull || value &gt;= from) &amp;&amp; (tonull || value &lt;= to));
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">geo_distance</span><span class="hljs-params">()</span> </span>{</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>TODO code here</p>
</div>
<div class="content"><div class='highlight'><pre> }
};</pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>we OR across fields but AND across terms in query string</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>._applyFreeTextQuery = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(results, queryObj)</span> </span>{
<span class="hljs-keyword">if</span> (queryObj.q) {
<span class="hljs-keyword">var</span> terms = queryObj.q.split(<span class="hljs-string">' '</span>);
<span class="hljs-keyword">var</span> patterns=_.map(terms, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(term)</span> </span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(term.toLowerCase());
});
results = _.filter(results, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(rawdoc)</span> </span>{
<span class="hljs-keyword">var</span> matches = <span class="hljs-literal">true</span>;
_.each(patterns, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(pattern)</span> </span>{
<span class="hljs-keyword">var</span> foundmatch = <span class="hljs-literal">false</span>;
_.each(self.fields, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field)</span> </span>{
<span class="hljs-keyword">var</span> value = rawdoc[field.id];
<span class="hljs-keyword">if</span> ((value !== <span class="hljs-literal">null</span>) &amp;&amp; (value !== <span class="hljs-literal">undefined</span>)) {
value = value.toString();
} <span class="hljs-keyword">else</span> {</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>value can be null (apparently in some cases)</p>
</div>
<div class="content"><div class='highlight'><pre> value = <span class="hljs-string">''</span>;
}</pre></div></div>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>TODO regexes?</p>
</div>
<div class="content"><div class='highlight'><pre> foundmatch = foundmatch || (pattern.test(value.toLowerCase()));</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>TODO: early out (once we are true should break to spare unnecessary testing)
if (foundmatch) return true;</p>
</div>
<div class="content"><div class='highlight'><pre> });
matches = matches &amp;&amp; foundmatch;</pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>TODO: early out (once false should break to spare unnecessary testing)
if (!matches) return false;</p>
</div>
<div class="content"><div class='highlight'><pre> });
<span class="hljs-keyword">return</span> matches;
});
}
<span class="hljs-keyword">return</span> results;
};
<span class="hljs-keyword">this</span>.computeFacets = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(records, queryObj)</span> </span>{
<span class="hljs-keyword">var</span> facetResults = {};
<span class="hljs-keyword">if</span> (!queryObj.facets) {
<span class="hljs-keyword">return</span> facetResults;
}
_.each(queryObj.facets, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(query, facetId)</span> </span>{</pre></div></div>
</li>
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>TODO: remove dependency on recline.Model</p>
</div>
<div class="content"><div class='highlight'><pre> facetResults[facetId] = <span class="hljs-keyword">new</span> recline.Model.Facet({id: facetId}).toJSON();
facetResults[facetId].termsall = {};
});</pre></div></div>
</li>
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>faceting</p>
</div>
<div class="content"><div class='highlight'><pre> _.each(records, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span> </span>{
_.each(queryObj.facets, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(query, facetId)</span> </span>{
<span class="hljs-keyword">var</span> fieldId = query.terms.field;
<span class="hljs-keyword">var</span> val = doc[fieldId];
<span class="hljs-keyword">var</span> tmp = facetResults[facetId];
<span class="hljs-keyword">if</span> (val) {
tmp.termsall[val] = tmp.termsall[val] ? tmp.termsall[val] + <span class="hljs-number">1</span> : <span class="hljs-number">1</span>;
} <span class="hljs-keyword">else</span> {
tmp.missing = tmp.missing + <span class="hljs-number">1</span>;
}
});
});
_.each(queryObj.facets, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(query, facetId)</span> </span>{
<span class="hljs-keyword">var</span> tmp = facetResults[facetId];
<span class="hljs-keyword">var</span> terms = _.map(tmp.termsall, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(count, term)</span> </span>{
<span class="hljs-keyword">return</span> { term: term, count: count };
});
tmp.terms = _.sortBy(terms, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(item)</span> </span>{</pre></div></div>
</li>
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>want descending order</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> -item.count;
});
tmp.terms = tmp.terms.slice(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>);
});
<span class="hljs-keyword">return</span> facetResults;
};
};
}(<span class="hljs-keyword">this</span>.recline.Backend.Memory));</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,236 +0,0 @@
<!DOCTYPE html> <html> <head> <title>demo.search.app.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> demo.search.app.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>(c) Open Knowledge Foundation 2012. Dedicated to the public domain. Please
use and reuse freely - you don't even need to credit (though a link back to
ReclineJS.com is always appreciated)!</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <h2>Our main loop - on document ready</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nx">jQuery</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">$el</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;.search-here&#39;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <h3>Overview</h3>
<p>We have a slightly more complex setup than is needed to allow for using
this demo with different backends</p>
<p>There are 2 alternatives: more complex and a simpler one</p>
<p>If you just want to see how this work skip to the simple case ...</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <h3>1. More complex - use data from a backend configured in query string</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Check for config from url query string</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">config</span> <span class="o">=</span> <span class="nx">recline</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">parseQueryString</span><span class="p">(</span><span class="nb">decodeURIComponent</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">search</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">backend</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>If we had it hand off to our more complex example setup</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">setupMoreComplexExample</span><span class="p">(</span><span class="nx">config</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <h3>2. The simple example case</h3>
<p>We will just set up from some example local data (at the bottom of thile file)</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <h4>Create our Recline Dataset from sample local data</h4> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">dataset</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">recline</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">Dataset</span><span class="p">({</span>
<span class="nx">records</span><span class="o">:</span> <span class="nx">sampleData</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <h4>Custom template</h4>
<p>Create a custom template for rendering the records</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="s1">&#39; \</span>
<span class="s1"> &lt;div class=&quot;record&quot;&gt; \</span>
<span class="s1"> &lt;h3&gt; \</span>
<span class="s1"> {{title}} &lt;em&gt;by {{Author}}&lt;/em&gt; \</span>
<span class="s1"> &lt;/h3&gt; \</span>
<span class="s1"> &lt;p&gt;{{description}}&lt;/p&gt; \</span>
<span class="s1"> &lt;p&gt;&lt;code&gt;${{price}}&lt;/code&gt;&lt;/p&gt; \</span>
<span class="s1"> &lt;/div&gt; \</span>
<span class="s1"> &#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <h4>Set up the search View (using custom template)</h4> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">searchView</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span>
<span class="nx">el</span><span class="o">:</span> <span class="nx">$el</span><span class="p">,</span>
<span class="nx">model</span><span class="o">:</span> <span class="nx">dataset</span><span class="p">,</span>
<span class="nx">template</span><span class="o">:</span> <span class="nx">template</span>
<span class="p">});</span>
<span class="nx">searchView</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <h4>Optional - we configure the initial query a bit and set up facets</h4> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">dataset</span><span class="p">.</span><span class="nx">queryState</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span>
<span class="nx">size</span><span class="o">:</span> <span class="mi">10</span>
<span class="p">},</span>
<span class="p">{</span><span class="nx">silent</span><span class="o">:</span> <span class="kc">true</span><span class="p">}</span>
<span class="p">);</span>
<span class="nx">dataset</span><span class="p">.</span><span class="nx">queryState</span><span class="p">.</span><span class="nx">addFacet</span><span class="p">(</span><span class="s1">&#39;Author&#39;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <h4>Finally - now do the first query</h4>
<p>After this point the Search View will take over handling queries!</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">dataset</span><span class="p">.</span><span class="nx">query</span><span class="p">();</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <h2>Simple Search View</h2>
<p>This is a simple bespoke Backbone view for the Search. It Pulls together
various Recline UI components and the central Dataset and Query (state)
object</p>
<p>It also provides simple support for customization e.g. of template for list of results</p>
<pre><code> var view = new SearchView({
el: $('some-element'),
model: dataset
// EITHER a mustache template (passed a JSON version of recline.Model.Record
// OR a function which receives a record in JSON form and returns html
template: mustache-template-or-function
});
</code></pre> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">SearchView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">el</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">);</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">bindAll</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s1">&#39;render&#39;</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">recordTemplate</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">template</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Every time we do a search the recline.Dataset.records Backbone
collection will get reset. We want to re-render each time!</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;reset&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">templateResults</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">template</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>overall template for this view</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">template</span><span class="o">:</span> <span class="s1">&#39; \</span>
<span class="s1"> &lt;div class=&quot;controls&quot;&gt; \</span>
<span class="s1"> &lt;div class=&quot;query-here&quot;&gt;&lt;/div&gt; \</span>
<span class="s1"> &lt;/div&gt; \</span>
<span class="s1"> &lt;div class=&quot;total&quot;&gt;&lt;h2&gt;&lt;span&gt;&lt;/span&gt; records found&lt;/h2&gt;&lt;/div&gt; \</span>
<span class="s1"> &lt;div class=&quot;body&quot;&gt; \</span>
<span class="s1"> &lt;div class=&quot;sidebar&quot;&gt;&lt;/div&gt; \</span>
<span class="s1"> &lt;div class=&quot;results&quot;&gt; \</span>
<span class="s1"> {{{results}}} \</span>
<span class="s1"> &lt;/div&gt; \</span>
<span class="s1"> &lt;/div&gt; \</span>
<span class="s1"> &lt;div class=&quot;pager-here&quot;&gt;&lt;/div&gt; \</span>
<span class="s1"> &#39;</span><span class="p">,</span>
</pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>render the view</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">results</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">templateResults</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">results</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">(),</span> <span class="k">this</span><span class="p">.</span><span class="nx">templateResults</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;\n&#39;</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>templateResults is just for one result ...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tmpl</span> <span class="o">=</span> <span class="s1">&#39;{{#records}}&#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">templateResults</span> <span class="o">+</span> <span class="s1">&#39;{{/records}}&#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">results</span> <span class="o">=</span> <span class="nx">Mustache</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">tmpl</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">records</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">()</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">html</span> <span class="o">=</span> <span class="nx">Mustache</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">template</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">results</span><span class="o">:</span> <span class="nx">results</span>
<span class="p">});</span>
<span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="nx">html</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>Set the total records found info</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="s1">&#39;.total span&#39;</span><span class="p">).</span><span class="nx">text</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">recordCount</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <h3>Now setup all the extra mini-widgets</h3>
<p>Facets, Pager, QueryEditor etc</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">recline</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">FacetViewer</span><span class="p">({</span>
<span class="nx">model</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">model</span>
<span class="p">});</span>
<span class="nx">view</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span>
<span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="s1">&#39;.sidebar&#39;</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">view</span><span class="p">.</span><span class="nx">el</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">pager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">recline</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">Pager</span><span class="p">({</span>
<span class="nx">model</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">queryState</span>
<span class="p">});</span>
<span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="s1">&#39;.pager-here&#39;</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">pager</span><span class="p">.</span><span class="nx">el</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">queryEditor</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">recline</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">QueryEditor</span><span class="p">({</span>
<span class="nx">model</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">queryState</span>
<span class="p">});</span>
<span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="s1">&#39;.query-here&#39;</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">queryEditor</span><span class="p">.</span><span class="nx">el</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <hr />
<h2>Custom code very specific to this demo</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>e.g. to provide custom templates for the google doc and openspending examples</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <h3>Handle case where we get data from a specific backend</h3>
<p>Includes providing custom templates</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">setupMoreComplexExample</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">$el</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;.search-here&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">dataset</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">recline</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">Dataset</span><span class="p">(</span><span class="nx">config</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>async as may be fetching remote</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">dataset</span><span class="p">.</span><span class="nx">fetch</span><span class="p">().</span><span class="nx">done</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">templates</span><span class="p">[</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;url&#39;</span><span class="p">)]</span> <span class="o">||</span> <span class="nx">templates</span><span class="p">[</span><span class="s1">&#39;generic&#39;</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">searchView</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SearchView</span><span class="p">({</span>
<span class="nx">el</span><span class="o">:</span> <span class="nx">$el</span><span class="p">,</span>
<span class="nx">model</span><span class="o">:</span> <span class="nx">dataset</span><span class="p">,</span>
<span class="nx">template</span><span class="o">:</span> <span class="nx">template</span>
<span class="p">});</span>
<span class="nx">searchView</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span>
<span class="nx">dataset</span><span class="p">.</span><span class="nx">queryState</span><span class="p">.</span><span class="nx">set</span><span class="p">({</span>
<span class="nx">size</span><span class="o">:</span> <span class="mi">5</span>
<span class="p">},</span>
<span class="p">{</span><span class="nx">silent</span><span class="o">:</span> <span class="kc">true</span><span class="p">}</span>
<span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;url&#39;</span><span class="p">)</span> <span class="k">in</span> <span class="nx">templates</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>for gdocs example</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">dataset</span><span class="p">.</span><span class="nx">queryState</span><span class="p">.</span><span class="nx">addFacet</span><span class="p">(</span><span class="s1">&#39;cause&#39;</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">dataset</span><span class="p">.</span><span class="nx">query</span><span class="p">();</span>
<span class="p">});</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">templates</span> <span class="o">=</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>generic template function</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s1">&#39;generic&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">record</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="s1">&#39;&lt;div class=&quot;record&quot;&gt; \</span>
<span class="s1"> &lt;ul&gt; \</span>
<span class="s1"> {{#data}} \</span>
<span class="s1"> &lt;li&gt;{{key}}: {{value}}&lt;/li&gt; \</span>
<span class="s1"> {{/data}} \</span>
<span class="s1"> &lt;/ul&gt; \</span>
<span class="s1"> &lt;/div&gt; \</span>
<span class="s1"> &#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">record</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">{</span> <span class="nx">key</span><span class="o">:</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="nx">record</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="p">};</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">Mustache</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">data</span><span class="o">:</span> <span class="nx">data</span>
<span class="p">});</span>
<span class="p">},</span>
<span class="s1">&#39;http://openspending.org/api/search&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">record</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">record</span><span class="p">[</span><span class="s1">&#39;time&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nx">record</span><span class="p">[</span><span class="s1">&#39;time.label_facet&#39;</span><span class="p">]</span>
<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="s1">&#39;&lt;div class=&quot;record&quot;&gt; \</span>
<span class="s1"> &lt;h3&gt; \</span>
<span class="s1"> &lt;a href=&quot;http://openspending.org/{{record.dataset}}/entries/{{record.id}}&quot;&gt;{{record.dataset}} {{record.time}}&lt;/a&gt; \</span>
<span class="s1"> &amp;ndash; &lt;img src=&quot;http://openspending.org/static/img/icons/cd_16x16.png&quot; /&gt; {{amount_formatted}} \</span>
<span class="s1"> &lt;/h3&gt; \</span>
<span class="s1"> &lt;ul&gt; \</span>
<span class="s1"> {{#data}} \</span>
<span class="s1"> &lt;li&gt;{{key}}: {{value}}&lt;/li&gt; \</span>
<span class="s1"> {{/data}} \</span>
<span class="s1"> &lt;/ul&gt; \</span>
<span class="s1"> &lt;/div&gt; \</span>
<span class="s1"> &#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">record</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">key</span> <span class="o">!=</span><span class="s1">&#39;_id&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">key</span> <span class="o">!=</span> <span class="s1">&#39;id&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">data</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span> <span class="nx">key</span><span class="o">:</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="nx">record</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="p">});</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">Mustache</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">record</span><span class="o">:</span> <span class="nx">record</span><span class="p">,</span>
<span class="nx">amount_formatted</span><span class="o">:</span> <span class="nx">formatAmount</span><span class="p">(</span><span class="nx">record</span><span class="p">[</span><span class="s1">&#39;amount&#39;</span><span class="p">]),</span>
<span class="nx">data</span><span class="o">:</span> <span class="nx">data</span>
<span class="p">});</span>
<span class="p">},</span>
<span class="s1">&#39;https://docs.google.com/spreadsheet/ccc?key=0Aon3JiuouxLUdExXSTl2Y01xZEszOTBFZjVzcGtzVVE&#39;</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">record</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="s1">&#39;&lt;div class=&quot;record&quot;&gt; \</span>
<span class="s1"> &lt;h3&gt; \</span>
<span class="s1"> {{record.incidentsite}} &amp;ndash; {{record.datereported}} &amp;ndash; {{record.estimatedspillvolumebbl}} barrels \</span>
<span class="s1"> &lt;/h3&gt; \</span>
<span class="s1"> &lt;ul&gt; \</span>
<span class="s1"> {{#data}} \</span>
<span class="s1"> &lt;li&gt;{{key}}: {{value}}&lt;/li&gt; \</span>
<span class="s1"> {{/data}} \</span>
<span class="s1"> &lt;/ul&gt; \</span>
<span class="s1"> &lt;/div&gt; \</span>
<span class="s1"> &#39;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">record</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">data</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span> <span class="nx">key</span><span class="o">:</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="nx">record</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="p">});</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">Mustache</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">record</span><span class="o">:</span> <span class="nx">record</span><span class="p">,</span>
<span class="nx">data</span><span class="o">:</span> <span class="nx">data</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">sampleData</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;War and Peace&#39;</span><span class="p">,</span>
<span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;The epic tale of love, war and history&#39;</span><span class="p">,</span>
<span class="nx">Author</span><span class="o">:</span> <span class="s1">&#39;Tolstoy&#39;</span><span class="p">,</span>
<span class="nx">price</span><span class="o">:</span> <span class="mf">7.99</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Anna Karenina&#39;</span><span class="p">,</span>
<span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;How things go wrong in love and ultimately lead to suicide. This is why you should not have affairs, girls!&#39;</span><span class="p">,</span>
<span class="nx">Author</span><span class="o">:</span> <span class="s1">&#39;Tolstoy&#39;</span><span class="p">,</span>
<span class="nx">price</span><span class="o">:</span> <span class="mf">8.50</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="nx">title</span><span class="o">:</span> <span class="s2">&quot;Fathers and Sons&quot;</span><span class="p">,</span>
<span class="nx">description</span><span class="o">:</span> <span class="s2">&quot;Another 19th century Russian novel&quot;</span><span class="p">,</span>
<span class="nx">Author</span><span class="o">:</span> <span class="s2">&quot;Turgenev&quot;</span><span class="p">,</span>
<span class="nx">price</span><span class="o">:</span> <span class="mi">11</span>
<span class="p">}</span>
<span class="p">];</span>
<span class="kd">var</span> <span class="nx">formatAmount</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">num</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">billion</span> <span class="o">=</span> <span class="mi">1000000000</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">million</span> <span class="o">=</span> <span class="mi">1000000</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">thousand</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">numabs</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">abs</span><span class="p">(</span><span class="nx">num</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">numabs</span> <span class="o">&gt;</span> <span class="nx">billion</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">num</span> <span class="o">/</span> <span class="nx">billion</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;bn&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">numabs</span> <span class="o">&gt;</span> <span class="p">(</span><span class="nx">million</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">num</span> <span class="o">/</span> <span class="nx">million</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;m&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">numabs</span> <span class="o">&gt;</span> <span class="nx">thousand</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">num</span> <span class="o">/</span> <span class="nx">thousand</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;k&#39;</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">num</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -1,518 +0,0 @@
/*--------------------- Typography ----------------------------*/
@font-face {
font-family: 'aller-light';
src: url('public/fonts/aller-light.eot');
src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'),
url('public/fonts/aller-light.woff') format('woff'),
url('public/fonts/aller-light.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'aller-bold';
src: url('public/fonts/aller-bold.eot');
src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'),
url('public/fonts/aller-bold.woff') format('woff'),
url('public/fonts/aller-bold.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'roboto-black';
src: url('public/fonts/roboto-black.eot');
src: url('public/fonts/roboto-black.eot?#iefix') format('embedded-opentype'),
url('public/fonts/roboto-black.woff') format('woff'),
url('public/fonts/roboto-black.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
/*--------------------- Layout ----------------------------*/
html { height: 100%; }
body {
font-family: "aller-light";
font-size: 14px;
line-height: 18px;
color: #30404f;
margin: 0; padding: 0;
height:100%;
}
#container { min-height: 100%; }
a {
color: #000;
}
b, strong {
font-weight: normal;
font-family: "aller-bold";
}
p {
margin: 15px 0 0px;
}
.annotation ul, .annotation ol {
margin: 25px 0;
}
.annotation ul li, .annotation ol li {
font-size: 14px;
line-height: 18px;
margin: 10px 0;
}
h1, h2, h3, h4, h5, h6 {
color: #112233;
line-height: 1em;
font-weight: normal;
font-family: "roboto-black";
text-transform: uppercase;
margin: 30px 0 15px 0;
}
h1 {
margin-top: 40px;
}
h2 {
font-size: 1.26em;
}
hr {
border: 0;
background: 1px #ddd;
height: 1px;
margin: 20px 0;
}
pre, tt, code {
font-size: 12px; line-height: 16px;
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0;
}
.annotation pre {
display: block;
margin: 0;
padding: 7px 10px;
background: #fcfcfc;
-moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
-webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
overflow-x: auto;
}
.annotation pre code {
border: 0;
padding: 0;
background: transparent;
}
blockquote {
border-left: 5px solid #ccc;
margin: 0;
padding: 1px 0 1px 1em;
}
.sections blockquote p {
font-family: Menlo, Consolas, Monaco, monospace;
font-size: 12px; line-height: 16px;
color: #999;
margin: 10px 0 0;
white-space: pre-wrap;
}
ul.sections {
list-style: none;
padding:0 0 5px 0;;
margin:0;
}
/*
Force border-box so that % widths fit the parent
container without overlap because of margin/padding.
More Info : http://www.quirksmode.org/css/box.html
*/
ul.sections > li > div {
-moz-box-sizing: border-box; /* firefox */
-ms-box-sizing: border-box; /* ie */
-webkit-box-sizing: border-box; /* webkit */
-khtml-box-sizing: border-box; /* konqueror */
box-sizing: border-box; /* css3 */
}
/*---------------------- Jump Page -----------------------------*/
#jump_to, #jump_page {
margin: 0;
background: white;
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
font: 16px Arial;
cursor: pointer;
text-align: right;
list-style: none;
}
#jump_to a {
text-decoration: none;
}
#jump_to a.large {
display: none;
}
#jump_to a.small {
font-size: 22px;
font-weight: bold;
color: #676767;
}
#jump_to, #jump_wrapper {
position: fixed;
right: 0; top: 0;
padding: 10px 15px;
margin:0;
}
#jump_wrapper {
display: none;
padding:0;
}
#jump_to:hover #jump_wrapper {
display: block;
}
#jump_page_wrapper{
position: fixed;
right: 0;
top: 0;
bottom: 0;
}
#jump_page {
padding: 5px 0 3px;
margin: 0 0 25px 25px;
max-height: 100%;
overflow: auto;
}
#jump_page .source {
display: block;
padding: 15px;
text-decoration: none;
border-top: 1px solid #eee;
}
#jump_page .source:hover {
background: #f5f5ff;
}
#jump_page .source:first-child {
}
/*---------------------- Low resolutions (> 320px) ---------------------*/
@media only screen and (min-width: 320px) {
.pilwrap { display: none; }
ul.sections > li > div {
display: block;
padding:5px 10px 0 10px;
}
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
padding-left: 30px;
}
ul.sections > li > div.content {
overflow-x:auto;
-webkit-box-shadow: inset 0 0 5px #e5e5ee;
box-shadow: inset 0 0 5px #e5e5ee;
border: 1px solid #dedede;
margin:5px 10px 5px 10px;
padding-bottom: 5px;
}
ul.sections > li > div.annotation pre {
margin: 7px 0 7px;
padding-left: 15px;
}
ul.sections > li > div.annotation p tt, .annotation code {
background: #f8f8ff;
border: 1px solid #dedede;
font-size: 12px;
padding: 0 0.2em;
}
}
/*---------------------- (> 481px) ---------------------*/
@media only screen and (min-width: 481px) {
#container {
position: relative;
}
body {
background-color: #F5F5FF;
font-size: 15px;
line-height: 21px;
}
pre, tt, code {
line-height: 18px;
}
p, ul, ol {
margin: 0 0 15px;
}
#jump_to {
padding: 5px 10px;
}
#jump_wrapper {
padding: 0;
}
#jump_to, #jump_page {
font: 10px Arial;
text-transform: uppercase;
}
#jump_page .source {
padding: 5px 10px;
}
#jump_to a.large {
display: inline-block;
}
#jump_to a.small {
display: none;
}
#background {
position: absolute;
top: 0; bottom: 0;
width: 350px;
background: #fff;
border-right: 1px solid #e5e5ee;
z-index: -1;
}
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
padding-left: 40px;
}
ul.sections > li {
white-space: nowrap;
}
ul.sections > li > div {
display: inline-block;
}
ul.sections > li > div.annotation {
max-width: 350px;
min-width: 350px;
min-height: 5px;
padding: 13px;
overflow-x: hidden;
white-space: normal;
vertical-align: top;
text-align: left;
}
ul.sections > li > div.annotation pre {
margin: 15px 0 15px;
padding-left: 15px;
}
ul.sections > li > div.content {
padding: 13px;
vertical-align: top;
border: none;
-webkit-box-shadow: none;
box-shadow: none;
}
.pilwrap {
position: relative;
display: inline;
}
.pilcrow {
font: 12px Arial;
text-decoration: none;
color: #454545;
position: absolute;
top: 3px; left: -20px;
padding: 1px 2px;
opacity: 0;
-webkit-transition: opacity 0.2s linear;
}
.for-h1 .pilcrow {
top: 47px;
}
.for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {
top: 35px;
}
ul.sections > li > div.annotation:hover .pilcrow {
opacity: 1;
}
}
/*---------------------- (> 1025px) ---------------------*/
@media only screen and (min-width: 1025px) {
body {
font-size: 16px;
line-height: 24px;
}
#background {
width: 525px;
}
ul.sections > li > div.annotation {
max-width: 525px;
min-width: 525px;
padding: 10px 25px 1px 50px;
}
ul.sections > li > div.content {
padding: 9px 15px 16px 25px;
}
}
/*---------------------- Syntax Highlighting -----------------------------*/
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
pre code {
display: block; padding: 0.5em;
color: #000;
background: #f8f8ff
}
pre .hljs-comment,
pre .hljs-template_comment,
pre .hljs-diff .hljs-header,
pre .hljs-javadoc {
color: #408080;
font-style: italic
}
pre .hljs-keyword,
pre .hljs-assignment,
pre .hljs-literal,
pre .hljs-css .hljs-rule .hljs-keyword,
pre .hljs-winutils,
pre .hljs-javascript .hljs-title,
pre .hljs-lisp .hljs-title,
pre .hljs-subst {
color: #954121;
/*font-weight: bold*/
}
pre .hljs-number,
pre .hljs-hexcolor {
color: #40a070
}
pre .hljs-string,
pre .hljs-tag .hljs-value,
pre .hljs-phpdoc,
pre .hljs-tex .hljs-formula {
color: #219161;
}
pre .hljs-title,
pre .hljs-id {
color: #19469D;
}
pre .hljs-params {
color: #00F;
}
pre .hljs-javascript .hljs-title,
pre .hljs-lisp .hljs-title,
pre .hljs-subst {
font-weight: normal
}
pre .hljs-class .hljs-title,
pre .hljs-haskell .hljs-label,
pre .hljs-tex .hljs-command {
color: #458;
font-weight: bold
}
pre .hljs-tag,
pre .hljs-tag .hljs-title,
pre .hljs-rules .hljs-property,
pre .hljs-django .hljs-tag .hljs-keyword {
color: #000080;
font-weight: normal
}
pre .hljs-attribute,
pre .hljs-variable,
pre .hljs-instancevar,
pre .hljs-lisp .hljs-body {
color: #008080
}
pre .hljs-regexp {
color: #B68
}
pre .hljs-class {
color: #458;
font-weight: bold
}
pre .hljs-symbol,
pre .hljs-ruby .hljs-symbol .hljs-string,
pre .hljs-ruby .hljs-symbol .hljs-keyword,
pre .hljs-ruby .hljs-symbol .hljs-keymethods,
pre .hljs-lisp .hljs-keyword,
pre .hljs-tex .hljs-special,
pre .hljs-input_number {
color: #990073
}
pre .hljs-builtin,
pre .hljs-constructor,
pre .hljs-built_in,
pre .hljs-lisp .hljs-title {
color: #0086b3
}
pre .hljs-preprocessor,
pre .hljs-pi,
pre .hljs-doctype,
pre .hljs-shebang,
pre .hljs-cdata {
color: #999;
font-weight: bold
}
pre .hljs-deletion {
background: #fdd
}
pre .hljs-addition {
background: #dfd
}
pre .hljs-diff .hljs-change {
background: #0086b3
}
pre .hljs-chunk {
color: #aaa
}
pre .hljs-tex .hljs-formula {
opacity: 0.5;
}

View File

@@ -1,215 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>ecma-fixes.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>ecma-fixes.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
<p>This file adds in full array method support in browsers that dont support it
see: <a href="http://stackoverflow.com/questions/2790001/fixing-javascript-array-functions-in-internet-explorer-indexof-foreach-etc">http://stackoverflow.com/questions/2790001/fixing-javascript-array-functions-in-internet-explorer-indexof-foreach-etc</a></p>
</div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Add ECMA262-5 Array methods if not supported natively</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> (!(<span class="hljs-string">'indexOf'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">Array</span>.prototype)) {
<span class="hljs-built_in">Array</span>.prototype.indexOf= <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(find, i <span class="hljs-comment">/*opt*/</span>)</span> </span>{
<span class="hljs-keyword">if</span> (i===<span class="hljs-literal">undefined</span>) i= <span class="hljs-number">0</span>;
<span class="hljs-keyword">if</span> (i&lt;<span class="hljs-number">0</span>) i+= <span class="hljs-keyword">this</span>.length;
<span class="hljs-keyword">if</span> (i&lt;<span class="hljs-number">0</span>) i= <span class="hljs-number">0</span>;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> n= <span class="hljs-keyword">this</span>.length; i&lt;n; i++)
<span class="hljs-keyword">if</span> (i <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span> &amp;&amp; <span class="hljs-keyword">this</span>[i]===find)
<span class="hljs-keyword">return</span> i;
<span class="hljs-keyword">return</span> -<span class="hljs-number">1</span>;
};
}
<span class="hljs-keyword">if</span> (!(<span class="hljs-string">'lastIndexOf'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">Array</span>.prototype)) {
<span class="hljs-built_in">Array</span>.prototype.lastIndexOf= <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(find, i <span class="hljs-comment">/*opt*/</span>)</span> </span>{
<span class="hljs-keyword">if</span> (i===<span class="hljs-literal">undefined</span>) i= <span class="hljs-keyword">this</span>.length-<span class="hljs-number">1</span>;
<span class="hljs-keyword">if</span> (i&lt;<span class="hljs-number">0</span>) i+= <span class="hljs-keyword">this</span>.length;
<span class="hljs-keyword">if</span> (i&gt;<span class="hljs-keyword">this</span>.length-<span class="hljs-number">1</span>) i= <span class="hljs-keyword">this</span>.length-<span class="hljs-number">1</span>;
<span class="hljs-keyword">for</span> (i++; i--&gt;<span class="hljs-number">0</span>;) <span class="hljs-comment">/* i++ because from-argument is sadly inclusive */</span>
<span class="hljs-keyword">if</span> (i <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span> &amp;&amp; <span class="hljs-keyword">this</span>[i]===find)
<span class="hljs-keyword">return</span> i;
<span class="hljs-keyword">return</span> -<span class="hljs-number">1</span>;
};
}
<span class="hljs-keyword">if</span> (!(<span class="hljs-string">'forEach'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">Array</span>.prototype)) {
<span class="hljs-built_in">Array</span>.prototype.forEach= <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(action, that <span class="hljs-comment">/*opt*/</span>)</span> </span>{
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i= <span class="hljs-number">0</span>, n= <span class="hljs-keyword">this</span>.length; i&lt;n; i++)
<span class="hljs-keyword">if</span> (i <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span>)
action.call(that, <span class="hljs-keyword">this</span>[i], i, <span class="hljs-keyword">this</span>);
};
}
<span class="hljs-keyword">if</span> (!(<span class="hljs-string">'map'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">Array</span>.prototype)) {
<span class="hljs-built_in">Array</span>.prototype.map= <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(mapper, that <span class="hljs-comment">/*opt*/</span>)</span> </span>{
<span class="hljs-keyword">var</span> other= <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(<span class="hljs-keyword">this</span>.length);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i= <span class="hljs-number">0</span>, n= <span class="hljs-keyword">this</span>.length; i&lt;n; i++)
<span class="hljs-keyword">if</span> (i <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span>)
other[i]= mapper.call(that, <span class="hljs-keyword">this</span>[i], i, <span class="hljs-keyword">this</span>);
<span class="hljs-keyword">return</span> other;
};
}
<span class="hljs-keyword">if</span> (!(<span class="hljs-string">'filter'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">Array</span>.prototype)) {
<span class="hljs-built_in">Array</span>.prototype.filter= <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(filter, that <span class="hljs-comment">/*opt*/</span>)</span> </span>{
<span class="hljs-keyword">var</span> other= [], v;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>, n= <span class="hljs-keyword">this</span>.length; i&lt;n; i++)
<span class="hljs-keyword">if</span> (i <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span> &amp;&amp; filter.call(that, v= <span class="hljs-keyword">this</span>[i], i, <span class="hljs-keyword">this</span>))
other.push(v);
<span class="hljs-keyword">return</span> other;
};
}
<span class="hljs-keyword">if</span> (!(<span class="hljs-string">'every'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">Array</span>.prototype)) {
<span class="hljs-built_in">Array</span>.prototype.every= <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(tester, that <span class="hljs-comment">/*opt*/</span>)</span> </span>{
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i= <span class="hljs-number">0</span>, n= <span class="hljs-keyword">this</span>.length; i&lt;n; i++)
<span class="hljs-keyword">if</span> (i <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span> &amp;&amp; !tester.call(that, <span class="hljs-keyword">this</span>[i], i, <span class="hljs-keyword">this</span>))
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
};
}
<span class="hljs-keyword">if</span> (!(<span class="hljs-string">'some'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">Array</span>.prototype)) {
<span class="hljs-built_in">Array</span>.prototype.some= <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(tester, that <span class="hljs-comment">/*opt*/</span>)</span> </span>{
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i= <span class="hljs-number">0</span>, n= <span class="hljs-keyword">this</span>.length; i&lt;n; i++)
<span class="hljs-keyword">if</span> (i <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span> &amp;&amp; tester.call(that, <span class="hljs-keyword">this</span>[i], i, <span class="hljs-keyword">this</span>))
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
};
}</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -1,375 +0,0 @@
/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
/* ==========================================================================
HTML5 display definitions
========================================================================== */
/*
* Corrects `block` display not defined in IE 8/9.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section,
summary {
display: block;
}
/*
* Corrects `inline-block` display not defined in IE 8/9.
*/
audio,
canvas,
video {
display: inline-block;
}
/*
* Prevents modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/*
* Addresses styling for `hidden` attribute not present in IE 8/9.
*/
[hidden] {
display: none;
}
/* ==========================================================================
Base
========================================================================== */
/*
* 1. Sets default font family to sans-serif.
* 2. Prevents iOS text size adjust after orientation change, without disabling
* user zoom.
*/
html {
font-family: sans-serif; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-ms-text-size-adjust: 100%; /* 2 */
}
/*
* Removes default margin.
*/
body {
margin: 0;
}
/* ==========================================================================
Links
========================================================================== */
/*
* Addresses `outline` inconsistency between Chrome and other browsers.
*/
a:focus {
outline: thin dotted;
}
/*
* Improves readability when focused and also mouse hovered in all browsers.
*/
a:active,
a:hover {
outline: 0;
}
/* ==========================================================================
Typography
========================================================================== */
/*
* Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
* Safari 5, and Chrome.
*/
h1 {
font-size: 2em;
}
/*
* Addresses styling not present in IE 8/9, Safari 5, and Chrome.
*/
abbr[title] {
border-bottom: 1px dotted;
}
/*
* Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
*/
b,
strong {
font-weight: bold;
}
/*
* Addresses styling not present in Safari 5 and Chrome.
*/
dfn {
font-style: italic;
}
/*
* Addresses styling not present in IE 8/9.
*/
mark {
background: #ff0;
color: #000;
}
/*
* Corrects font family set oddly in Safari 5 and Chrome.
*/
code,
kbd,
pre,
samp {
font-family: monospace, serif;
font-size: 1em;
}
/*
* Improves readability of pre-formatted text in all browsers.
*/
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
}
/*
* Sets consistent quote types.
*/
q {
quotes: "\201C" "\201D" "\2018" "\2019";
}
/*
* Addresses inconsistent and variable font size in all browsers.
*/
small {
font-size: 80%;
}
/*
* Prevents `sub` and `sup` affecting `line-height` in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* ==========================================================================
Embedded content
========================================================================== */
/*
* Removes border when inside `a` element in IE 8/9.
*/
img {
border: 0;
}
/*
* Corrects overflow displayed oddly in IE 9.
*/
svg:not(:root) {
overflow: hidden;
}
/* ==========================================================================
Figures
========================================================================== */
/*
* Addresses margin not present in IE 8/9 and Safari 5.
*/
figure {
margin: 0;
}
/* ==========================================================================
Forms
========================================================================== */
/*
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/*
* 1. Corrects color not being inherited in IE 8/9.
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
*/
legend {
border: 0; /* 1 */
padding: 0; /* 2 */
}
/*
* 1. Corrects font family not being inherited in all browsers.
* 2. Corrects font size not being inherited in all browsers.
* 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
*/
button,
input,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 2 */
margin: 0; /* 3 */
}
/*
* Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
button,
input {
line-height: normal;
}
/*
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Corrects inability to style clickable `input` types in iOS.
* 3. Improves usability and consistency of cursor style between image-type
* `input` and others.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
/*
* Re-set default cursor for disabled elements.
*/
button[disabled],
input[disabled] {
cursor: default;
}
/*
* 1. Addresses box sizing set to `content-box` in IE 8/9.
* 2. Removes excess padding in IE 8/9.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/*
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
* (include `-moz` to future-proof).
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/*
* Removes inner padding and search cancel button in Safari 5 and Chrome
* on OS X.
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/*
* Removes inner padding and border in Firefox 4+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/*
* 1. Removes default vertical scrollbar in IE 8/9.
* 2. Improves readability and alignment in all browsers.
*/
textarea {
overflow: auto; /* 1 */
vertical-align: top; /* 2 */
}
/* ==========================================================================
Tables
========================================================================== */
/*
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}

View File

@@ -1,865 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>view.flot.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>view.flot.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<h2 id="graph-view-for-a-dataset-using-flot-graphing-library-">Graph view for a Dataset using Flot graphing library.</h2>
<p>Initialization arguments (in a hash in first parameter):</p>
<ul>
<li>model: recline.Model.Dataset</li>
<li><p>state: (optional) configuration hash of form:</p>
<pre><code> {
group: {column name <span class="hljs-keyword">for</span> x-axis},
series: [{column name <span class="hljs-keyword">for</span> series A}, {column name series B}, ... ],
<span class="hljs-comment">// options are: lines, points, lines-and-points, bars, columns</span>
graphType: <span class="hljs-string">'lines'</span>,
graphOptions: {custom [flot options]}
}
</code></pre></li>
</ul>
<p>NB: should <em>not</em> provide an el argument to the view but must let the view
generate the element itself (you can then append view.el to the DOM.</p>
</div>
<div class="content"><div class='highlight'><pre>my.Flot = Backbone.View.extend({
template: <span class="hljs-string">' \
&lt;div class="recline-flot"&gt; \
&lt;div class="panel graph" style="display: block;"&gt; \
&lt;div class="js-temp-notice alert alert-warning alert-block"&gt; \
&lt;h3 class="alert-heading"&gt;Hey there!&lt;/h3&gt; \
&lt;p&gt;There\'s no graph here yet because we don\'t know what fields you\'d like to see plotted.&lt;/p&gt; \
&lt;p&gt;Please tell us by &lt;strong&gt;using the menu on the right&lt;/strong&gt; and a graph will automatically appear.&lt;/p&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
'</span>,
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(options)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">this</span>.graphColors = [<span class="hljs-string">"#edc240"</span>, <span class="hljs-string">"#afd8f8"</span>, <span class="hljs-string">"#cb4b4b"</span>, <span class="hljs-string">"#4da74d"</span>, <span class="hljs-string">"#9440ed"</span>];
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>, <span class="hljs-string">'redraw'</span>, <span class="hljs-string">'_toolTip'</span>, <span class="hljs-string">'_xaxisLabel'</span>);
<span class="hljs-keyword">this</span>.needToRedraw = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model, <span class="hljs-string">'change'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'reset add'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.records, <span class="hljs-string">'reset add'</span>, <span class="hljs-keyword">this</span>.redraw);
<span class="hljs-keyword">var</span> stateData = _.extend({
group: <span class="hljs-literal">null</span>,</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>so that at least one series chooser box shows up</p>
</div>
<div class="content"><div class='highlight'><pre> series: [],
graphType: <span class="hljs-string">'lines-and-points'</span>
},
options.state
);
<span class="hljs-keyword">this</span>.state = <span class="hljs-keyword">new</span> recline.Model.ObjectState(stateData);
<span class="hljs-keyword">this</span>.previousTooltipPoint = {x: <span class="hljs-literal">null</span>, y: <span class="hljs-literal">null</span>};
<span class="hljs-keyword">this</span>.editor = <span class="hljs-keyword">new</span> my.FlotControls({
model: <span class="hljs-keyword">this</span>.model,
state: <span class="hljs-keyword">this</span>.state.toJSON()
});
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.editor.state, <span class="hljs-string">'change'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
self.state.set(self.editor.state.toJSON());
self.redraw();
});
<span class="hljs-keyword">this</span>.elSidebar = <span class="hljs-keyword">this</span>.editor.$el;
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> tmplData = <span class="hljs-keyword">this</span>.model.toTemplateJSON();
<span class="hljs-keyword">var</span> htmls = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(htmls);
<span class="hljs-keyword">this</span>.$graph = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.panel.graph'</span>);
<span class="hljs-keyword">this</span>.$graph.on(<span class="hljs-string">"plothover"</span>, <span class="hljs-keyword">this</span>._toolTip);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
},
remove: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">this</span>.editor.remove();
Backbone.View.prototype.remove.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
},
redraw: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>There are issues generating a Flot graph if either:</p>
<ul>
<li>The relevant div that graph attaches to his hidden at the moment of creating the plot — Flot will complain with
Uncaught Invalid dimensions for plot, width = 0, height = 0</li>
<li>There is no data for the plot — either same error or may have issues later with errors like non-existent node-value</li>
</ul>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> areWeVisible = !jQuery.expr.filters.hidden(<span class="hljs-keyword">this</span>.el);
<span class="hljs-keyword">if</span> ((!areWeVisible || <span class="hljs-keyword">this</span>.model.records.length === <span class="hljs-number">0</span>)) {
<span class="hljs-keyword">this</span>.needToRedraw = <span class="hljs-literal">true</span>;
<span class="hljs-keyword">return</span>;
}</pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>check we have something to plot</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'group'</span>) &amp;&amp; <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'series'</span>)) {
<span class="hljs-keyword">var</span> series = <span class="hljs-keyword">this</span>.createSeries();
<span class="hljs-keyword">var</span> options = <span class="hljs-keyword">this</span>.getGraphOptions(<span class="hljs-keyword">this</span>.state.attributes.graphType, series[<span class="hljs-number">0</span>].data.length);
<span class="hljs-keyword">this</span>.plot = $.plot(<span class="hljs-keyword">this</span>.$graph, series, options);
}
},
show: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>because we cannot redraw when hidden we may need to when becoming visible</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.needToRedraw) {
<span class="hljs-keyword">this</span>.redraw();
}
},</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>infoboxes on mouse hover on points/bars etc</p>
</div>
<div class="content"><div class='highlight'><pre> _toolTip: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(event, pos, item)</span> </span>{
<span class="hljs-keyword">if</span> (item) {
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.previousTooltipPoint.x !== item.dataIndex ||
<span class="hljs-keyword">this</span>.previousTooltipPoint.y !== item.seriesIndex) {
<span class="hljs-keyword">this</span>.previousTooltipPoint.x = item.dataIndex;
<span class="hljs-keyword">this</span>.previousTooltipPoint.y = item.seriesIndex;
$(<span class="hljs-string">"#recline-flot-tooltip"</span>).remove();
<span class="hljs-keyword">var</span> x = item.datapoint[<span class="hljs-number">0</span>].toFixed(<span class="hljs-number">2</span>),
y = item.datapoint[<span class="hljs-number">1</span>].toFixed(<span class="hljs-number">2</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.attributes.graphType === <span class="hljs-string">'bars'</span>) {
x = item.datapoint[<span class="hljs-number">1</span>].toFixed(<span class="hljs-number">2</span>),
y = item.datapoint[<span class="hljs-number">0</span>].toFixed(<span class="hljs-number">2</span>);
}
<span class="hljs-keyword">var</span> content = _.template(<span class="hljs-string">'&lt;%= group %&gt; = &lt;%= x %&gt;, &lt;%= series %&gt; = &lt;%= y %&gt;'</span>, {
group: <span class="hljs-keyword">this</span>.state.attributes.group,
x: <span class="hljs-keyword">this</span>._xaxisLabel(x),
series: item.series.label,
y: y
});</pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>use a different tooltip location offset for bar charts</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> xLocation, yLocation;
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.attributes.graphType === <span class="hljs-string">'bars'</span>) {
xLocation = item.pageX + <span class="hljs-number">15</span>;
yLocation = item.pageY - <span class="hljs-number">10</span>;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.attributes.graphType === <span class="hljs-string">'columns'</span>) {
xLocation = item.pageX + <span class="hljs-number">15</span>;
yLocation = item.pageY;
} <span class="hljs-keyword">else</span> {
xLocation = item.pageX + <span class="hljs-number">10</span>;
yLocation = item.pageY - <span class="hljs-number">20</span>;
}
$(<span class="hljs-string">'&lt;div id="recline-flot-tooltip"&gt;'</span> + content + <span class="hljs-string">'&lt;/div&gt;'</span>).css({
top: yLocation,
left: xLocation
}).appendTo(<span class="hljs-string">"body"</span>).fadeIn(<span class="hljs-number">200</span>);
}
} <span class="hljs-keyword">else</span> {
$(<span class="hljs-string">"#recline-flot-tooltip"</span>).remove();
<span class="hljs-keyword">this</span>.previousTooltipPoint.x = <span class="hljs-literal">null</span>;
<span class="hljs-keyword">this</span>.previousTooltipPoint.y = <span class="hljs-literal">null</span>;
}
},
_xaxisLabel: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(x)</span> </span>{
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>._groupFieldIsDateTime()) {</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>oddly x comes through as milliseconds <em>string</em> (rather than int
or float) so we have to reparse</p>
</div>
<div class="content"><div class='highlight'><pre> x = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-built_in">parseFloat</span>(x)).toLocaleDateString();
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.xvaluesAreIndex) {
x = <span class="hljs-built_in">parseInt</span>(x, <span class="hljs-number">10</span>);</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>HACK: deal with bar graph style cases where x-axis items were strings
In this case x at this point is the index of the item in the list of
records not its actual x-axis value</p>
</div>
<div class="content"><div class='highlight'><pre> x = <span class="hljs-keyword">this</span>.model.records.models[x].get(<span class="hljs-keyword">this</span>.state.attributes.group);
}
<span class="hljs-keyword">return</span> x;
},</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<h3 id="getgraphoptions">getGraphOptions</h3>
<p>Get options for Flot Graph</p>
<p>needs to be function as can depend on state</p>
<p>@param typeId graphType id (lines, lines-and-points etc)
@param numPoints the number of points that will be plotted</p>
</div>
<div class="content"><div class='highlight'><pre> getGraphOptions: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(typeId, numPoints)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> groupFieldIsDateTime = self._groupFieldIsDateTime();
<span class="hljs-keyword">var</span> xaxis = {};
<span class="hljs-keyword">if</span> (!groupFieldIsDateTime) {
xaxis.tickFormatter = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(x)</span> </span>{</pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>convert x to a string and make sure that it is not too long or the
tick labels will overlap
TODO: find a more accurate way of calculating the size of tick labels</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> label = self._xaxisLabel(x) || <span class="hljs-string">""</span>;
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> label !== <span class="hljs-string">'string'</span>) {
label = label.toString();
}
<span class="hljs-keyword">if</span> (self.state.attributes.graphType !== <span class="hljs-string">'bars'</span> &amp;&amp; label.length &gt; <span class="hljs-number">10</span>) {
label = label.slice(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>) + <span class="hljs-string">"..."</span>;
}
<span class="hljs-keyword">return</span> label;
};
}</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>for labels case we only want ticks at the label intervals
HACK: however we also get this case with Date fields. In that case we
could have a lot of values and so we limit to max 15 (we assume)</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.xvaluesAreIndex) {
<span class="hljs-keyword">var</span> numTicks = <span class="hljs-built_in">Math</span>.min(<span class="hljs-keyword">this</span>.model.records.length, <span class="hljs-number">15</span>);
<span class="hljs-keyword">var</span> increment = <span class="hljs-keyword">this</span>.model.records.length / numTicks;
<span class="hljs-keyword">var</span> ticks = [];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;numTicks; i++) {
ticks.push(<span class="hljs-built_in">parseInt</span>(i*increment, <span class="hljs-number">10</span>));
}
xaxis.ticks = ticks;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (groupFieldIsDateTime) {
xaxis.mode = <span class="hljs-string">'time'</span>;
}
<span class="hljs-keyword">var</span> yaxis = {};
yaxis.autoscale = <span class="hljs-literal">true</span>;
yaxis.autoscaleMargin = <span class="hljs-number">0.02</span>;
<span class="hljs-keyword">var</span> legend = {};
legend.position = <span class="hljs-string">'ne'</span>;
<span class="hljs-keyword">var</span> grid = {};
grid.hoverable = <span class="hljs-literal">true</span>;
grid.clickable = <span class="hljs-literal">true</span>;
grid.borderColor = <span class="hljs-string">"#aaaaaa"</span>;
grid.borderWidth = <span class="hljs-number">1</span>;
<span class="hljs-keyword">var</span> optionsPerGraphType = {
lines: {
legend: legend,
colors: <span class="hljs-keyword">this</span>.graphColors,
lines: { show: <span class="hljs-literal">true</span> },
xaxis: xaxis,
yaxis: yaxis,
grid: grid
},
points: {
legend: legend,
colors: <span class="hljs-keyword">this</span>.graphColors,
points: { show: <span class="hljs-literal">true</span>, hitRadius: <span class="hljs-number">5</span> },
xaxis: xaxis,
yaxis: yaxis,
grid: grid
},
<span class="hljs-string">'lines-and-points'</span>: {
legend: legend,
colors: <span class="hljs-keyword">this</span>.graphColors,
points: { show: <span class="hljs-literal">true</span>, hitRadius: <span class="hljs-number">5</span> },
lines: { show: <span class="hljs-literal">true</span> },
xaxis: xaxis,
yaxis: yaxis,
grid: grid
},
bars: {
legend: legend,
colors: <span class="hljs-keyword">this</span>.graphColors,
lines: { show: <span class="hljs-literal">false</span> },
xaxis: yaxis,
yaxis: xaxis,
grid: grid,
bars: {
show: <span class="hljs-literal">true</span>,
horizontal: <span class="hljs-literal">true</span>,
shadowSize: <span class="hljs-number">0</span>,
align: <span class="hljs-string">'center'</span>,
barWidth: <span class="hljs-number">0.8</span>
}
},
columns: {
legend: legend,
colors: <span class="hljs-keyword">this</span>.graphColors,
lines: { show: <span class="hljs-literal">false</span> },
xaxis: xaxis,
yaxis: yaxis,
grid: grid,
bars: {
show: <span class="hljs-literal">true</span>,
horizontal: <span class="hljs-literal">false</span>,
shadowSize: <span class="hljs-number">0</span>,
align: <span class="hljs-string">'center'</span>,
barWidth: <span class="hljs-number">0.8</span>
}
}
};
<span class="hljs-keyword">if</span> (self.state.get(<span class="hljs-string">'graphOptions'</span>)) {
<span class="hljs-keyword">return</span> _.extend(optionsPerGraphType[typeId],
self.state.get(<span class="hljs-string">'graphOptions'</span>));
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">return</span> optionsPerGraphType[typeId];
}
},
_groupFieldIsDateTime: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> xfield = <span class="hljs-keyword">this</span>.model.fields.get(<span class="hljs-keyword">this</span>.state.attributes.group);
<span class="hljs-keyword">var</span> xtype = xfield.get(<span class="hljs-string">'type'</span>);
<span class="hljs-keyword">var</span> isDateTime = (xtype === <span class="hljs-string">'date'</span> || xtype === <span class="hljs-string">'date-time'</span> || xtype === <span class="hljs-string">'time'</span>);
<span class="hljs-keyword">return</span> isDateTime;
},
createSeries: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
self.xvaluesAreIndex = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">var</span> series = [];
<span class="hljs-keyword">var</span> xfield = self.model.fields.get(self.state.attributes.group);
<span class="hljs-keyword">var</span> isDateTime = self._groupFieldIsDateTime();
_.each(<span class="hljs-keyword">this</span>.state.attributes.series, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field)</span> </span>{
<span class="hljs-keyword">var</span> points = [];
<span class="hljs-keyword">var</span> fieldLabel = self.model.fields.get(field).get(<span class="hljs-string">'label'</span>);
<span class="hljs-keyword">if</span> (isDateTime){
<span class="hljs-keyword">var</span> cast = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(x)</span></span>{
<span class="hljs-keyword">var</span> _date = moment(<span class="hljs-built_in">String</span>(x));
<span class="hljs-keyword">if</span> (_date.isValid()) {
x = _date.toDate().getTime();
}
<span class="hljs-keyword">return</span> x
}
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">var</span> raw = _.map(self.model.records.models,
<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc, index)</span></span>{
<span class="hljs-keyword">return</span> doc.getFieldValueUnrendered(xfield)
});
<span class="hljs-keyword">if</span> (_.all(raw, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(x)</span></span>{ <span class="hljs-keyword">return</span> !<span class="hljs-built_in">isNaN</span>(<span class="hljs-built_in">parseFloat</span>(x)) })){
<span class="hljs-keyword">var</span> cast = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(x)</span></span>{ <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseFloat</span>(x) }
} <span class="hljs-keyword">else</span> {
self.xvaluesAreIndex = <span class="hljs-literal">true</span>
}
}
_.each(self.model.records.models, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc, index)</span> </span>{
<span class="hljs-keyword">if</span>(self.xvaluesAreIndex){
<span class="hljs-keyword">var</span> x = index;
}<span class="hljs-keyword">else</span>{
<span class="hljs-keyword">var</span> x = cast(doc.getFieldValueUnrendered(xfield));
}
<span class="hljs-keyword">var</span> yfield = self.model.fields.get(field);
<span class="hljs-keyword">var</span> y = <span class="hljs-built_in">parseFloat</span>(doc.getFieldValueUnrendered(yfield));
<span class="hljs-keyword">if</span> (self.state.attributes.graphType == <span class="hljs-string">'bars'</span>) {
points.push([y, x]);
} <span class="hljs-keyword">else</span> {
points.push([x, y]);
}
});
series.push({
data: points,
label: fieldLabel,
hoverable: <span class="hljs-literal">true</span>
});
});
<span class="hljs-keyword">return</span> series;
}
});
my.FlotControls = Backbone.View.extend({
className: <span class="hljs-string">"editor"</span>,
template: <span class="hljs-string">' \
&lt;div class="editor"&gt; \
&lt;form class="form-stacked"&gt; \
&lt;div class="clearfix"&gt; \
&lt;div class="form-group"&gt; \
&lt;label&gt;Graph Type&lt;/label&gt; \
&lt;div class="input editor-type"&gt; \
&lt;select class="form-control"&gt; \
&lt;option value="lines-and-points"&gt;Lines and Points&lt;/option&gt; \
&lt;option value="lines"&gt;Lines&lt;/option&gt; \
&lt;option value="points"&gt;Points&lt;/option&gt; \
&lt;option value="bars"&gt;Bars&lt;/option&gt; \
&lt;option value="columns"&gt;Columns&lt;/option&gt; \
&lt;/select&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
&lt;div class="form-group"&gt; \
&lt;label&gt;Group Column (Axis 1)&lt;/label&gt; \
&lt;div class="input editor-group"&gt; \
&lt;select class="form-control"&gt; \
&lt;option value=""&gt;Please choose ...&lt;/option&gt; \
{{#fields}} \
&lt;option value="{{id}}"&gt;{{label}}&lt;/option&gt; \
{{/fields}} \
&lt;/select&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
&lt;div class="editor-series-group"&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
&lt;div class="editor-buttons"&gt; \
&lt;button class="btn btn-default editor-add"&gt;Add Series&lt;/button&gt; \
&lt;/div&gt; \
&lt;div class="editor-buttons editor-submit" comment="hidden temporarily" style="display: none;"&gt; \
&lt;button class="editor-save"&gt;Save&lt;/button&gt; \
&lt;input type="hidden" class="editor-id" value="chart-1" /&gt; \
&lt;/div&gt; \
&lt;/form&gt; \
&lt;/div&gt; \
'</span>,
templateSeriesEditor: <span class="hljs-string">' \
&lt;div class="editor-series js-series-{{seriesIndex}}"&gt; \
&lt;div class="form-group"&gt; \
&lt;label&gt;Series &lt;span&gt;{{seriesName}} (Axis 2)&lt;/span&gt; \
[&lt;a href="#remove" class="action-remove-series"&gt;Remove&lt;/a&gt;] \
&lt;/label&gt; \
&lt;div class="input"&gt; \
&lt;select class="form-control"&gt; \
{{#fields}} \
&lt;option value="{{id}}"&gt;{{label}}&lt;/option&gt; \
{{/fields}} \
&lt;/select&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
'</span>,
events: {
<span class="hljs-string">'change form select'</span>: <span class="hljs-string">'onEditorSubmit'</span>,
<span class="hljs-string">'click .editor-add'</span>: <span class="hljs-string">'_onAddSeries'</span>,
<span class="hljs-string">'click .action-remove-series'</span>: <span class="hljs-string">'removeSeries'</span>
},
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(options)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'reset add'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.state = <span class="hljs-keyword">new</span> recline.Model.ObjectState(options.state);
<span class="hljs-keyword">this</span>.render();
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> tmplData = <span class="hljs-keyword">this</span>.model.toTemplateJSON();
<span class="hljs-keyword">var</span> htmls = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(htmls);</pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>set up editor from state</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'graphType'</span>)) {
<span class="hljs-keyword">this</span>._selectOption(<span class="hljs-string">'.editor-type'</span>, <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'graphType'</span>));
}
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'group'</span>)) {
<span class="hljs-keyword">this</span>._selectOption(<span class="hljs-string">'.editor-group'</span>, <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'group'</span>));
}</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>ensure at least one series box shows up</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> tmpSeries = [<span class="hljs-string">""</span>];
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'series'</span>).length &gt; <span class="hljs-number">0</span>) {
tmpSeries = <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'series'</span>);
}
_.each(tmpSeries, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(series, idx)</span> </span>{
self.addSeries(idx);
self._selectOption(<span class="hljs-string">'.editor-series.js-series-'</span> + idx, series);
});
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
},</pre></div></div>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Private: Helper function to select an option from a select list</p>
</div>
<div class="content"><div class='highlight'><pre> _selectOption: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(id,value)</span></span>{
<span class="hljs-keyword">var</span> options = <span class="hljs-keyword">this</span>.$el.find(id + <span class="hljs-string">' select &gt; option'</span>);
<span class="hljs-keyword">if</span> (options) {
options.each(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(opt)</span></span>{
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.value == value) {
$(<span class="hljs-keyword">this</span>).attr(<span class="hljs-string">'selected'</span>,<span class="hljs-string">'selected'</span>);
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}
});
}
},
onEditorSubmit: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
<span class="hljs-keyword">var</span> select = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-group select'</span>);
<span class="hljs-keyword">var</span> $editor = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> $series = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-series select'</span>);
<span class="hljs-keyword">var</span> series = $series.map(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> $(<span class="hljs-keyword">this</span>).val();
});
<span class="hljs-keyword">var</span> updatedState = {
series: $.makeArray(series),
group: <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-group select'</span>).val(),
graphType: <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-type select'</span>).val()
};
<span class="hljs-keyword">this</span>.state.set(updatedState);
},</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Public: Adds a new empty series select box to the editor.</p>
<p>@param [int] idx index of this series in the list of series</p>
<p>Returns itself.</p>
</div>
<div class="content"><div class='highlight'><pre> addSeries: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(idx)</span> </span>{
<span class="hljs-keyword">var</span> data = _.extend({
seriesIndex: idx,
seriesName: <span class="hljs-built_in">String</span>.fromCharCode(idx + <span class="hljs-number">64</span> + <span class="hljs-number">1</span>)
}, <span class="hljs-keyword">this</span>.model.toTemplateJSON());
<span class="hljs-keyword">var</span> htmls = Mustache.render(<span class="hljs-keyword">this</span>.templateSeriesEditor, data);
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.editor-series-group'</span>).append(htmls);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
},
_onAddSeries: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">this</span>.addSeries(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'series'</span>).length);
},</pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>Public: Removes a series list item from the editor.</p>
<p>Also updates the labels of the remaining series elements.</p>
</div>
<div class="content"><div class='highlight'><pre> removeSeries: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $el = $(e.target);
$el.parent().parent().remove();
<span class="hljs-keyword">this</span>.onEditorSubmit();
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,141 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>view.graph.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>view.graph.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
<span class="hljs-keyword">this</span>.recline.View.Graph = <span class="hljs-keyword">this</span>.recline.View.Flot;
<span class="hljs-keyword">this</span>.recline.View.GraphControls = <span class="hljs-keyword">this</span>.recline.View.FlotControls;</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,606 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>view.grid.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>view.grid.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<h2 id="-data-grid-dataset-view">(Data) Grid Dataset View</h2>
<p>Provides a tabular view on a Dataset.</p>
<p>Initialize it with a <code>recline.Model.Dataset</code>.</p>
</div>
<div class="content"><div class='highlight'><pre>my.Grid = Backbone.View.extend({
tagName: <span class="hljs-string">"div"</span>,
className: <span class="hljs-string">"recline-grid-container"</span>,
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(modelEtc)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>, <span class="hljs-string">'onHorizontalScroll'</span>);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.records, <span class="hljs-string">'add reset remove'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.tempState = {};
<span class="hljs-keyword">var</span> state = _.extend({
hiddenFields: []
}, modelEtc.state
);
<span class="hljs-keyword">this</span>.state = <span class="hljs-keyword">new</span> recline.Model.ObjectState(state);
},
events: {</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>does not work here so done at end of render function
scroll .recline-grid tbody: onHorizontalScroll</p>
</div>
<div class="content"><div class='highlight'><pre> },</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>======================================================</p>
</div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Column and row menus</p>
</div>
<div class="content"><div class='highlight'><pre>
setColumnSort: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(order)</span> </span>{
<span class="hljs-keyword">var</span> sort = [{}];
sort[<span class="hljs-number">0</span>][<span class="hljs-keyword">this</span>.tempState.currentColumn] = {order: order};
<span class="hljs-keyword">this</span>.model.query({sort: sort});
},
hideColumn: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> hiddenFields = <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'hiddenFields'</span>);
hiddenFields.push(<span class="hljs-keyword">this</span>.tempState.currentColumn);
<span class="hljs-keyword">this</span>.state.set({hiddenFields: hiddenFields});</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>change event not being triggered (because it is an array?) so trigger manually</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.state.trigger(<span class="hljs-string">'change'</span>);
<span class="hljs-keyword">this</span>.render();
},
showColumn: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
<span class="hljs-keyword">var</span> hiddenFields = _.without(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'hiddenFields'</span>), $(e.target).data(<span class="hljs-string">'column'</span>));
<span class="hljs-keyword">this</span>.state.set({hiddenFields: hiddenFields});
<span class="hljs-keyword">this</span>.render();
},
onHorizontalScroll: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
<span class="hljs-keyword">var</span> currentScroll = $(e.target).scrollLeft();
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.recline-grid thead tr'</span>).scrollLeft(currentScroll);
},</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>======================================================</p>
</div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<h4 id="templating">Templating</h4>
</div>
<div class="content"><div class='highlight'><pre> template: <span class="hljs-string">' \
&lt;div class="table-container"&gt; \
&lt;table class="recline-grid table-striped table-condensed" cellspacing="0"&gt; \
&lt;thead class="fixed-header"&gt; \
&lt;tr&gt; \
{{#fields}} \
&lt;th class="column-header {{#hidden}}hidden{{/hidden}}" data-field="{{id}}" style="width: {{width}}px; max-width: {{width}}px; min-width: {{width}}px;" title="{{label}}"&gt; \
&lt;span class="column-header-name"&gt;{{label}}&lt;/span&gt; \
&lt;/th&gt; \
{{/fields}} \
&lt;th class="last-header" style="width: {{lastHeaderWidth}}px; max-width: {{lastHeaderWidth}}px; min-width: {{lastHeaderWidth}}px; padding: 0; margin: 0;"&gt;&lt;/th&gt; \
&lt;/tr&gt; \
&lt;/thead&gt; \
&lt;tbody class="scroll-content"&gt;&lt;/tbody&gt; \
&lt;/table&gt; \
&lt;/div&gt; \
'</span>,
toTemplateJSON: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> modelData = <span class="hljs-keyword">this</span>.model.toJSON();
modelData.notEmpty = ( <span class="hljs-keyword">this</span>.fields.length &gt; <span class="hljs-number">0</span> );</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>TODO: move this sort of thing into a toTemplateJSON method on Dataset?</p>
</div>
<div class="content"><div class='highlight'><pre> modelData.fields = <span class="hljs-keyword">this</span>.fields.map(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field)</span> </span>{
<span class="hljs-keyword">return</span> field.toJSON();
});</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>last header width = scroll bar - border (2px) */</p>
</div>
<div class="content"><div class='highlight'><pre> modelData.lastHeaderWidth = <span class="hljs-keyword">this</span>.scrollbarDimensions.width - <span class="hljs-number">2</span>;
<span class="hljs-keyword">return</span> modelData;
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">this</span>.fields = <span class="hljs-keyword">new</span> recline.Model.FieldList(<span class="hljs-keyword">this</span>.model.fields.filter(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field)</span> </span>{
<span class="hljs-keyword">return</span> _.indexOf(self.state.get(<span class="hljs-string">'hiddenFields'</span>), field.id) == -<span class="hljs-number">1</span>;
}));
<span class="hljs-keyword">this</span>.scrollbarDimensions = <span class="hljs-keyword">this</span>.scrollbarDimensions || <span class="hljs-keyword">this</span>._scrollbarSize(); <span class="hljs-comment">// skip measurement if already have dimensions</span>
<span class="hljs-keyword">var</span> numFields = <span class="hljs-keyword">this</span>.fields.length;</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>compute field widths (-20 for first menu col + 10px for padding on each col and finally 16px for the scrollbar)</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> fullWidth = self.$el.width() - <span class="hljs-number">20</span> - <span class="hljs-number">10</span> * numFields - <span class="hljs-keyword">this</span>.scrollbarDimensions.width;
<span class="hljs-keyword">var</span> width = <span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">Math</span>.max(<span class="hljs-number">50</span>, fullWidth / numFields), <span class="hljs-number">10</span>);</pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>if columns extend outside viewport then remainder is 0 </p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> remainder = <span class="hljs-built_in">Math</span>.max(fullWidth - numFields * width,<span class="hljs-number">0</span>);
<span class="hljs-keyword">this</span>.fields.each(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field, idx)</span> </span>{</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>add the remainder to the first field width so we make up full col</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (idx === <span class="hljs-number">0</span>) {
field.set({width: width+remainder});
} <span class="hljs-keyword">else</span> {
field.set({width: width});
}
});
<span class="hljs-keyword">var</span> htmls = Mustache.render(<span class="hljs-keyword">this</span>.template, <span class="hljs-keyword">this</span>.toTemplateJSON());
<span class="hljs-keyword">this</span>.$el.html(htmls);
<span class="hljs-keyword">this</span>.model.records.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(doc)</span> </span>{
<span class="hljs-keyword">var</span> tr = $(<span class="hljs-string">'&lt;tr /&gt;'</span>);
self.$el.find(<span class="hljs-string">'tbody'</span>).append(tr);
<span class="hljs-keyword">var</span> newView = <span class="hljs-keyword">new</span> my.GridRow({
model: doc,
el: tr,
fields: self.fields
});
newView.render();
});</pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>hide extra header col if no scrollbar to avoid unsightly overhang</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> $tbody = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'tbody'</span>)[<span class="hljs-number">0</span>];
<span class="hljs-keyword">if</span> ($tbody.scrollHeight &lt;= $tbody.offsetHeight) {
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'th.last-header'</span>).hide();
}
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.recline-grid'</span>).toggleClass(<span class="hljs-string">'no-hidden'</span>, (self.state.get(<span class="hljs-string">'hiddenFields'</span>).length === <span class="hljs-number">0</span>));
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.recline-grid tbody'</span>).scroll(<span class="hljs-keyword">this</span>.onHorizontalScroll);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
},</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<h3 id="_scrollbarsize">_scrollbarSize</h3>
<p>Measure width of a vertical scrollbar and height of a horizontal scrollbar.</p>
<p>@return: { width: pixelWidth, height: pixelHeight }</p>
</div>
<div class="content"><div class='highlight'><pre> _scrollbarSize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> $c = $(<span class="hljs-string">"&lt;div style='position:absolute; top:-10000px; left:-10000px; width:100px; height:100px; overflow:scroll;'&gt;&lt;/div&gt;"</span>).appendTo(<span class="hljs-string">"body"</span>);
<span class="hljs-keyword">var</span> dim = { width: $c.width() - $c[<span class="hljs-number">0</span>].clientWidth + <span class="hljs-number">1</span>, height: $c.height() - $c[<span class="hljs-number">0</span>].clientHeight };
$c.remove();
<span class="hljs-keyword">return</span> dim;
}
});</pre></div></div>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<h2 id="gridrow-view-for-rendering-an-individual-record-">GridRow View for rendering an individual record.</h2>
<p>Since we want this to update in place it is up to creator to provider the element to attach to.</p>
<p>In addition you <em>must</em> pass in a FieldList in the constructor options. This should be list of fields for the Grid.</p>
<p>Example:</p>
<pre>
var row = new GridRow({
model: dataset-record,
el: dom-element,
fields: mydatasets.fields // a FieldList object
});
</pre>
</div>
<div class="content"><div class='highlight'><pre>my.GridRow = Backbone.View.extend({
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(initData)</span> </span>{
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);
<span class="hljs-keyword">this</span>._fields = initData.fields;
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model, <span class="hljs-string">'change'</span>, <span class="hljs-keyword">this</span>.render);
},
template: <span class="hljs-string">' \
{{#cells}} \
&lt;td data-field="{{field}}" style="width: {{width}}px; max-width: {{width}}px; min-width: {{width}}px;"&gt; \
&lt;div class="data-table-cell-content"&gt; \
&lt;a href="javascript:{}" class="data-table-cell-edit" title="Edit this cell"&gt;&amp;nbsp;&lt;/a&gt; \
&lt;div class="data-table-cell-value"&gt;{{{value}}}&lt;/div&gt; \
&lt;/div&gt; \
&lt;/td&gt; \
{{/cells}} \
'</span>,
events: {
<span class="hljs-string">'click .data-table-cell-edit'</span>: <span class="hljs-string">'onEditClick'</span>,
<span class="hljs-string">'click .data-table-cell-editor .okButton'</span>: <span class="hljs-string">'onEditorOK'</span>,
<span class="hljs-string">'click .data-table-cell-editor .cancelButton'</span>: <span class="hljs-string">'onEditorCancel'</span>
},
toTemplateJSON: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> doc = <span class="hljs-keyword">this</span>.model;
<span class="hljs-keyword">var</span> cellData = <span class="hljs-keyword">this</span>._fields.map(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field)</span> </span>{
<span class="hljs-keyword">return</span> {
field: field.id,
width: field.get(<span class="hljs-string">'width'</span>),
value: doc.getFieldValue(field)
};
});
<span class="hljs-keyword">return</span> { id: <span class="hljs-keyword">this</span>.id, cells: cellData };
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">this</span>.$el.attr(<span class="hljs-string">'data-id'</span>, <span class="hljs-keyword">this</span>.model.id);
<span class="hljs-keyword">var</span> html = Mustache.render(<span class="hljs-keyword">this</span>.template, <span class="hljs-keyword">this</span>.toTemplateJSON());
<span class="hljs-keyword">this</span>.$el.html(html);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
},</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>===================</p>
</div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>Cell Editor methods</p>
</div>
<div class="content"><div class='highlight'><pre>
cellEditorTemplate: <span class="hljs-string">' \
&lt;div class="menu-container data-table-cell-editor"&gt; \
&lt;textarea class="data-table-cell-editor-editor" bind="textarea"&gt;{{value}}&lt;/textarea&gt; \
&lt;div id="data-table-cell-editor-actions"&gt; \
&lt;div class="data-table-cell-editor-action"&gt; \
&lt;button class="okButton btn primary"&gt;Update&lt;/button&gt; \
&lt;button class="cancelButton btn danger"&gt;Cancel&lt;/button&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
'</span>,
onEditClick: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
<span class="hljs-keyword">var</span> editing = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.data-table-cell-editor-editor'</span>);
<span class="hljs-keyword">if</span> (editing.length &gt; <span class="hljs-number">0</span>) {
editing.parents(<span class="hljs-string">'.data-table-cell-value'</span>).html(editing.text()).siblings(<span class="hljs-string">'.data-table-cell-edit'</span>).removeClass(<span class="hljs-string">"hidden"</span>);
}
$(e.target).addClass(<span class="hljs-string">"hidden"</span>);
<span class="hljs-keyword">var</span> cell = $(e.target).siblings(<span class="hljs-string">'.data-table-cell-value'</span>);
cell.data(<span class="hljs-string">"previousContents"</span>, cell.text());
<span class="hljs-keyword">var</span> templated = Mustache.render(<span class="hljs-keyword">this</span>.cellEditorTemplate, {value: cell.text()});
cell.html(templated);
},
onEditorOK: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> cell = $(e.target);
<span class="hljs-keyword">var</span> rowId = cell.parents(<span class="hljs-string">'tr'</span>).attr(<span class="hljs-string">'data-id'</span>);
<span class="hljs-keyword">var</span> field = cell.parents(<span class="hljs-string">'td'</span>).attr(<span class="hljs-string">'data-field'</span>);
<span class="hljs-keyword">var</span> newValue = cell.parents(<span class="hljs-string">'.data-table-cell-editor'</span>).find(<span class="hljs-string">'.data-table-cell-editor-editor'</span>).val();
<span class="hljs-keyword">var</span> newData = {};
newData[field] = newValue;
<span class="hljs-keyword">this</span>.model.set(newData);
<span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'recline:flash'</span>, {message: <span class="hljs-string">"Updating row..."</span>, loader: <span class="hljs-literal">true</span>});
<span class="hljs-keyword">this</span>.model.save().then(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(response)</span> </span>{
<span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'recline:flash'</span>, {message: <span class="hljs-string">"Row updated successfully"</span>, category: <span class="hljs-string">'success'</span>});
})
.fail(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'recline:flash'</span>, {
message: <span class="hljs-string">'Error saving row'</span>,
category: <span class="hljs-string">'error'</span>,
persist: <span class="hljs-literal">true</span>
});
});
},
onEditorCancel: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
<span class="hljs-keyword">var</span> cell = $(e.target).parents(<span class="hljs-string">'.data-table-cell-value'</span>);
cell.html(cell.data(<span class="hljs-string">'previousContents'</span>)).siblings(<span class="hljs-string">'.data-table-cell-edit'</span>).removeClass(<span class="hljs-string">"hidden"</span>);
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,446 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>view.timeline.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>view.timeline.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>turn off unnecessary logging from VMM Timeline</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> VMM !== <span class="hljs-string">'undefined'</span>) {
VMM.debug = <span class="hljs-literal">false</span>;
}</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<h2 id="timeline">Timeline</h2>
<p>Timeline view using <a href="http://timeline.verite.co/">http://timeline.verite.co/</a></p>
</div>
<div class="content"><div class='highlight'><pre>my.Timeline = Backbone.View.extend({
template: <span class="hljs-string">' \
&lt;div class="recline-timeline"&gt; \
&lt;div id="vmm-timeline-id"&gt;&lt;/div&gt; \
&lt;/div&gt; \
'</span>,</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>These are the default (case-insensitive) names of field that are used if found.
If not found, the user will need to define these fields on initialization</p>
</div>
<div class="content"><div class='highlight'><pre> startFieldNames: [<span class="hljs-string">'date'</span>,<span class="hljs-string">'startdate'</span>, <span class="hljs-string">'start'</span>, <span class="hljs-string">'start-date'</span>],
endFieldNames: [<span class="hljs-string">'end'</span>,<span class="hljs-string">'endDate'</span>],
elementId: <span class="hljs-string">'#vmm-timeline-id'</span>,
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(options)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">this</span>.timeline = <span class="hljs-keyword">new</span> VMM.Timeline(<span class="hljs-keyword">this</span>.elementId);
<span class="hljs-keyword">this</span>._timelineIsInitialized = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'reset'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
self._setupTemporalField();
});
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.records, <span class="hljs-string">'all'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
self.reloadData();
});
<span class="hljs-keyword">var</span> stateData = _.extend({
startField: <span class="hljs-literal">null</span>,
endField: <span class="hljs-literal">null</span>,</pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>by default timelinejs (and browsers) will parse ambiguous dates in US format (mm/dd/yyyy)
set to true to interpret dd/dd/dddd as dd/mm/yyyy</p>
</div>
<div class="content"><div class='highlight'><pre> nonUSDates: <span class="hljs-literal">false</span>,
timelineJSOptions: {}
},
options.state
);
<span class="hljs-keyword">this</span>.state = <span class="hljs-keyword">new</span> recline.Model.ObjectState(stateData);
<span class="hljs-keyword">this</span>._setupTemporalField();
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> tmplData = {};
<span class="hljs-keyword">var</span> htmls = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(htmls);</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>can only call _initTimeline once view in DOM as Timeline uses $
internally to look up element</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ($(<span class="hljs-keyword">this</span>.elementId).length &gt; <span class="hljs-number">0</span>) {
<span class="hljs-keyword">this</span>._initTimeline();
}
},
show: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>only call _initTimeline once view in DOM as Timeline uses $ internally to look up element</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>._timelineIsInitialized === <span class="hljs-literal">false</span>) {
<span class="hljs-keyword">this</span>._initTimeline();
}
},
_initTimeline: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> data = <span class="hljs-keyword">this</span>._timelineJSON();
<span class="hljs-keyword">var</span> config = <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">"timelineJSOptions"</span>);
config.id = <span class="hljs-keyword">this</span>.elementId;
<span class="hljs-keyword">this</span>.timeline.init(config, data);
<span class="hljs-keyword">this</span>._timelineIsInitialized = <span class="hljs-literal">true</span>
},
reloadData: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>._timelineIsInitialized) {
<span class="hljs-keyword">var</span> data = <span class="hljs-keyword">this</span>._timelineJSON();
<span class="hljs-keyword">this</span>.timeline.reload(data);
}
},</pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Convert record to JSON for timeline</p>
<p>Designed to be overridden in client apps</p>
</div>
<div class="content"><div class='highlight'><pre> convertRecord: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(record, fields)</span> </span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._convertRecord(record, fields);
},</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>Internal method to generate a Timeline formatted entry</p>
</div>
<div class="content"><div class='highlight'><pre> _convertRecord: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(record, fields)</span> </span>{
<span class="hljs-keyword">var</span> start = <span class="hljs-keyword">this</span>._parseDate(record.get(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'startField'</span>)));
<span class="hljs-keyword">var</span> end = <span class="hljs-keyword">this</span>._parseDate(record.get(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'endField'</span>)));
<span class="hljs-keyword">if</span> (start) {
<span class="hljs-keyword">var</span> tlEntry = {
<span class="hljs-string">"startDate"</span>: start,
<span class="hljs-string">"endDate"</span>: end,
<span class="hljs-string">"headline"</span>: <span class="hljs-built_in">String</span>(record.get(<span class="hljs-string">'title'</span>) || <span class="hljs-string">''</span>),
<span class="hljs-string">"text"</span>: record.get(<span class="hljs-string">'description'</span>) || record.summary(),
<span class="hljs-string">"tag"</span>: record.get(<span class="hljs-string">'tags'</span>)
};
<span class="hljs-keyword">return</span> tlEntry;
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
},
_timelineJSON: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> out = {
<span class="hljs-string">'timeline'</span>: {
<span class="hljs-string">'type'</span>: <span class="hljs-string">'default'</span>,
<span class="hljs-string">'headline'</span>: <span class="hljs-string">''</span>,
<span class="hljs-string">'date'</span>: [
]
}
};
<span class="hljs-keyword">this</span>.model.records.each(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(record)</span> </span>{
<span class="hljs-keyword">var</span> newEntry = self.convertRecord(record, self.fields);
<span class="hljs-keyword">if</span> (newEntry) {
out.timeline.date.push(newEntry);
}
});</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>if no entries create a placeholder entry to prevent Timeline crashing with error</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (out.timeline.date.length === <span class="hljs-number">0</span>) {
<span class="hljs-keyword">var</span> tlEntry = {
<span class="hljs-string">"startDate"</span>: <span class="hljs-string">'2000,1,1'</span>,
<span class="hljs-string">"headline"</span>: <span class="hljs-string">'No data to show!'</span>
};
out.timeline.date.push(tlEntry);
}
<span class="hljs-keyword">return</span> out;
},</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>convert dates into a format TimelineJS will handle
TimelineJS does not document this at all so combo of read the code +
trial and error
Summary (AFAICt):
Preferred: [-]yyyy[,mm,dd,hh,mm,ss]
Supported: mm/dd/yyyy</p>
</div>
<div class="content"><div class='highlight'><pre> _parseDate: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(date)</span> </span>{
<span class="hljs-keyword">if</span> (!date) {
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
<span class="hljs-keyword">var</span> out = $.trim(date);
out = out.replace(<span class="hljs-regexp">/(\d)th/g</span>, <span class="hljs-string">'$1'</span>);
out = out.replace(<span class="hljs-regexp">/(\d)st/g</span>, <span class="hljs-string">'$1'</span>);
out = $.trim(out);
<span class="hljs-keyword">if</span> (out.match(<span class="hljs-regexp">/\d\d\d\d-\d\d-\d\d(T.*)?/</span>)) {
out = out.replace(<span class="hljs-regexp">/-/g</span>, <span class="hljs-string">','</span>).replace(<span class="hljs-string">'T'</span>, <span class="hljs-string">','</span>).replace(<span class="hljs-string">':'</span>,<span class="hljs-string">','</span>);
}
<span class="hljs-keyword">if</span> (out.match(<span class="hljs-regexp">/\d\d-\d\d-\d\d.*/</span>)) {
out = out.replace(<span class="hljs-regexp">/-/g</span>, <span class="hljs-string">'/'</span>);
}
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'nonUSDates'</span>)) {
<span class="hljs-keyword">var</span> parts = out.match(<span class="hljs-regexp">/(\d\d)\/(\d\d)\/(\d\d.*)/</span>);
<span class="hljs-keyword">if</span> (parts) {
out = [parts[<span class="hljs-number">2</span>], parts[<span class="hljs-number">1</span>], parts[<span class="hljs-number">3</span>]].join(<span class="hljs-string">'/'</span>);
}
}
<span class="hljs-keyword">return</span> out;
},
_setupTemporalField: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">this</span>.state.set({
startField: <span class="hljs-keyword">this</span>._checkField(<span class="hljs-keyword">this</span>.startFieldNames),
endField: <span class="hljs-keyword">this</span>._checkField(<span class="hljs-keyword">this</span>.endFieldNames)
});
},
_checkField: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(possibleFieldNames)</span> </span>{
<span class="hljs-keyword">var</span> modelFieldNames = <span class="hljs-keyword">this</span>.model.fields.pluck(<span class="hljs-string">'id'</span>);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; possibleFieldNames.length; i++){
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j = <span class="hljs-number">0</span>; j &lt; modelFieldNames.length; j++){
<span class="hljs-keyword">if</span> (modelFieldNames[j].toLowerCase() == possibleFieldNames[i].toLowerCase())
<span class="hljs-keyword">return</span> modelFieldNames[j];
}
}
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,259 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>widget.facetviewer.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>widget.facetviewer.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<h2 id="facetviewer">FacetViewer</h2>
<p>Widget for displaying facets </p>
<p>Usage:</p>
<pre><code> <span class="hljs-keyword">var</span> viewer = <span class="hljs-keyword">new</span> FacetViewer({
model: dataset
});
</code></pre>
</div>
<div class="content"><div class='highlight'><pre>my.FacetViewer = Backbone.View.extend({
className: <span class="hljs-string">'recline-facet-viewer'</span>,
template: <span class="hljs-string">' \
&lt;div class="facets"&gt; \
{{#facets}} \
&lt;div class="facet-summary" data-facet="{{id}}"&gt; \
&lt;h3&gt; \
{{id}} \
&lt;/h3&gt; \
&lt;ul class="facet-items"&gt; \
{{#terms}} \
&lt;li&gt;&lt;a class="facet-choice js-facet-filter" data-value="{{term}}" href="#{{term}}"&gt;{{term}} ({{count}})&lt;/a&gt;&lt;/li&gt; \
{{/terms}} \
{{#entries}} \
&lt;li&gt;&lt;a class="facet-choice js-facet-filter" data-value="{{time}}"&gt;{{term}} ({{count}})&lt;/a&gt;&lt;/li&gt; \
{{/entries}} \
&lt;/ul&gt; \
&lt;/div&gt; \
{{/facets}} \
&lt;/div&gt; \
'</span>,
events: {
<span class="hljs-string">'click .js-facet-filter'</span>: <span class="hljs-string">'onFacetFilter'</span>
},
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(model)</span> </span>{
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.facets, <span class="hljs-string">'all'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'all'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.render();
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> tmplData = {
fields: <span class="hljs-keyword">this</span>.model.fields.toJSON()
};
tmplData.facets = _.map(<span class="hljs-keyword">this</span>.model.facets.toJSON(), <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(facet)</span> </span>{
<span class="hljs-keyword">if</span> (facet._type === <span class="hljs-string">'date_histogram'</span>) {
facet.entries = _.map(facet.entries, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(entry)</span> </span>{
entry.term = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(entry.time).toDateString();
<span class="hljs-keyword">return</span> entry;
});
}
<span class="hljs-keyword">return</span> facet;
});
<span class="hljs-keyword">var</span> templated = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(templated);</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>are there actually any facets to show?</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.model.facets.length &gt; <span class="hljs-number">0</span>) {
<span class="hljs-keyword">this</span>.$el.show();
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">this</span>.$el.hide();
}
},
onHide: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">this</span>.$el.hide();
},
onFacetFilter: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $target= $(e.target);
<span class="hljs-keyword">var</span> fieldId = $target.closest(<span class="hljs-string">'.facet-summary'</span>).attr(<span class="hljs-string">'data-facet'</span>);
<span class="hljs-keyword">var</span> value = $target.attr(<span class="hljs-string">'data-value'</span>);
<span class="hljs-keyword">this</span>.model.queryState.addFilter({type: <span class="hljs-string">'term'</span>, field: fieldId, term: value});</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>have to trigger explicitly for some reason</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.model.query();
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,299 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>widget.fields.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>widget.fields.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span></pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Field Info</p>
<p>For each field</p>
<p>Id / Label / type / format</p>
</div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Editor — to change type (and possibly format)
Editor for show/hide …</p>
</div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>Summaries of fields</p>
<p>Top values / number empty
If number: max, min average …</p>
</div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Box to boot transform editor …</p>
</div>
<div class="content"><div class='highlight'><pre>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;
my.Fields = Backbone.View.extend({
className: <span class="hljs-string">'recline-fields-view'</span>,
template: <span class="hljs-string">' \
&lt;div class="panel-group fields-list well"&gt; \
&lt;h3&gt;Fields &lt;a href="#" class="js-show-hide"&gt;+&lt;/a&gt;&lt;/h3&gt; \
{{#fields}} \
&lt;div class="panel panel-default field"&gt; \
&lt;div class="panel-heading"&gt; \
&lt;i class="glyphicon glyphicon-file"&gt;&lt;/i&gt; \
&lt;h4&gt; \
{{label}} \
&lt;small&gt; \
{{type}} \
&lt;a class="accordion-toggle" data-toggle="collapse" href="#collapse{{id}}"&gt; &amp;raquo; &lt;/a&gt; \
&lt;/small&gt; \
&lt;/h4&gt; \
&lt;/div&gt; \
&lt;div id="collapse{{id}}" class="panel-collapse collapse"&gt; \
&lt;div class="panel-body"&gt; \
{{#facets}} \
&lt;div class="facet-summary" data-facet="{{id}}"&gt; \
&lt;ul class="facet-items"&gt; \
{{#terms}} \
&lt;li class="facet-item"&gt;&lt;span class="term"&gt;{{term}}&lt;/span&gt; &lt;span class="count"&gt;[{{count}}]&lt;/span&gt;&lt;/li&gt; \
{{/terms}} \
&lt;/ul&gt; \
&lt;/div&gt; \
{{/facets}} \
&lt;div class="clear"&gt;&lt;/div&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
{{/fields}} \
&lt;/div&gt; \
'</span>,
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(model)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>TODO: this is quite restrictive in terms of when it is re-run
e.g. a change in type will not trigger a re-run atm.
being more liberal (e.g. binding to all) can lead to being called a lot (e.g. for change:width)</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'reset'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(action)</span> </span>{
self.model.fields.each(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field)</span> </span>{
field.facets.unbind(<span class="hljs-string">'all'</span>, self.render);
field.facets.bind(<span class="hljs-string">'all'</span>, self.render);
});</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>fields can get reset or changed in which case we need to recalculate</p>
</div>
<div class="content"><div class='highlight'><pre> self.model.getFieldsSummary();
self.render();
});
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.collapse'</span>).collapse();
<span class="hljs-keyword">this</span>.render();
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> tmplData = {
fields: []
};
<span class="hljs-keyword">this</span>.model.fields.each(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(field)</span> </span>{
<span class="hljs-keyword">var</span> out = field.toJSON();
out.facets = field.facets.toJSON();
tmplData.fields.push(out);
});
<span class="hljs-keyword">var</span> templated = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(templated);
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,330 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>widget.filtereditor.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>widget.filtereditor.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;
my.FilterEditor = Backbone.View.extend({
className: <span class="hljs-string">'recline-filter-editor well'</span>,
template: <span class="hljs-string">' \
&lt;div class="filters"&gt; \
&lt;h3&gt;Filters&lt;/h3&gt; \
&lt;a href="#" class="js-add-filter"&gt;Add filter&lt;/a&gt; \
&lt;form class="form-stacked js-add" style="display: none;"&gt; \
&lt;div class="form-group"&gt; \
&lt;label&gt;Field&lt;/label&gt; \
&lt;select class="fields form-control"&gt; \
{{#fields}} \
&lt;option value="{{id}}"&gt;{{label}}&lt;/option&gt; \
{{/fields}} \
&lt;/select&gt; \
&lt;/div&gt; \
&lt;div class="form-group"&gt; \
&lt;label&gt;Filter type&lt;/label&gt; \
&lt;select class="filterType form-control"&gt; \
&lt;option value="term"&gt;Value&lt;/option&gt; \
&lt;option value="range"&gt;Range&lt;/option&gt; \
&lt;option value="geo_distance"&gt;Geo distance&lt;/option&gt; \
&lt;/select&gt; \
&lt;/div&gt; \
&lt;button type="submit" class="btn btn-default"&gt;Add&lt;/button&gt; \
&lt;/form&gt; \
&lt;form class="form-stacked js-edit"&gt; \
{{#filters}} \
{{{filterRender}}} \
{{/filters}} \
{{#filters.length}} \
&lt;button type="submit" class="btn btn-default"&gt;Update&lt;/button&gt; \
{{/filters.length}} \
&lt;/form&gt; \
&lt;/div&gt; \
'</span>,
filterTemplates: {
term: <span class="hljs-string">' \
&lt;div class="filter-{{type}} filter"&gt; \
&lt;fieldset&gt; \
&lt;legend&gt; \
{{field}} &lt;small&gt;{{type}}&lt;/small&gt; \
&lt;a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}"&gt;&amp;times;&lt;/a&gt; \
&lt;/legend&gt; \
&lt;input class="input-sm" type="text" value="{{term}}" name="term" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /&gt; \
&lt;/fieldset&gt; \
&lt;/div&gt; \
'</span>,
range: <span class="hljs-string">' \
&lt;div class="filter-{{type}} filter"&gt; \
&lt;fieldset&gt; \
&lt;legend&gt; \
{{field}} &lt;small&gt;{{type}}&lt;/small&gt; \
&lt;a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}"&gt;&amp;times;&lt;/a&gt; \
&lt;/legend&gt; \
&lt;div class="form-group"&gt; \
&lt;label class="control-label" for=""&gt;From&lt;/label&gt; \
&lt;input class="input-sm" type="text" value="{{from}}" name="from" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /&gt; \
&lt;/div&gt; \
&lt;div class="form-group"&gt; \
&lt;label class="control-label" for=""&gt;To&lt;/label&gt; \
&lt;input class="input-sm" type="text" value="{{to}}" name="to" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /&gt; \
&lt;/div&gt; \
&lt;/fieldset&gt; \
&lt;/div&gt; \
'</span>,
geo_distance: <span class="hljs-string">' \
&lt;div class="filter-{{type}} filter"&gt; \
&lt;fieldset&gt; \
&lt;legend&gt; \
{{field}} &lt;small&gt;{{type}}&lt;/small&gt; \
&lt;a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}"&gt;&amp;times;&lt;/a&gt; \
&lt;/legend&gt; \
&lt;div class="form-group"&gt; \
&lt;label class="control-label" for=""&gt;Longitude&lt;/label&gt; \
&lt;input class="input-sm" type="text" value="{{point.lon}}" name="lon" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /&gt; \
&lt;/div&gt; \
&lt;div class="form-group"&gt; \
&lt;label class="control-label" for=""&gt;Latitude&lt;/label&gt; \
&lt;input class="input-sm" type="text" value="{{point.lat}}" name="lat" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /&gt; \
&lt;/div&gt; \
&lt;div class="form-group"&gt; \
&lt;label class="control-label" for=""&gt;Distance (km)&lt;/label&gt; \
&lt;input class="input-sm" type="text" value="{{distance}}" name="distance" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /&gt; \
&lt;/div&gt; \
&lt;/fieldset&gt; \
&lt;/div&gt; \
'</span>
},
events: {
<span class="hljs-string">'click .js-remove-filter'</span>: <span class="hljs-string">'onRemoveFilter'</span>,
<span class="hljs-string">'click .js-add-filter'</span>: <span class="hljs-string">'onAddFilterShow'</span>,
<span class="hljs-string">'submit form.js-edit'</span>: <span class="hljs-string">'onTermFiltersUpdate'</span>,
<span class="hljs-string">'submit form.js-add'</span>: <span class="hljs-string">'onAddFilter'</span>
},
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'all'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.queryState, <span class="hljs-string">'change change:filters:new-blank'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.render();
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> tmplData = $.extend(<span class="hljs-literal">true</span>, {}, <span class="hljs-keyword">this</span>.model.queryState.toJSON());</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>we will use idx in list as there id …</p>
</div>
<div class="content"><div class='highlight'><pre> tmplData.filters = _.map(tmplData.filters, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(filter, idx)</span> </span>{
filter.id = idx;
<span class="hljs-keyword">return</span> filter;
});
tmplData.fields = <span class="hljs-keyword">this</span>.model.fields.toJSON();
tmplData.filterRender = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> Mustache.render(self.filterTemplates[<span class="hljs-keyword">this</span>.type], <span class="hljs-keyword">this</span>);
};
<span class="hljs-keyword">var</span> out = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(out);
},
onAddFilterShow: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $target = $(e.target);
$target.hide();
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'form.js-add'</span>).show();
},
onAddFilter: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $target = $(e.target);
$target.hide();
<span class="hljs-keyword">var</span> filterType = $target.find(<span class="hljs-string">'select.filterType'</span>).val();
<span class="hljs-keyword">var</span> field = $target.find(<span class="hljs-string">'select.fields'</span>).val();
<span class="hljs-keyword">this</span>.model.queryState.addFilter({type: filterType, field: field});
},
onRemoveFilter: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $target = $(e.target);
<span class="hljs-keyword">var</span> filterId = $target.attr(<span class="hljs-string">'data-filter-id'</span>);
<span class="hljs-keyword">this</span>.model.queryState.removeFilter(filterId);
},
onTermFiltersUpdate: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
e.preventDefault();
<span class="hljs-keyword">var</span> filters = self.model.queryState.get(<span class="hljs-string">'filters'</span>);
<span class="hljs-keyword">var</span> $form = $(e.target);
_.each($form.find(<span class="hljs-string">'input'</span>), <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(input)</span> </span>{
<span class="hljs-keyword">var</span> $input = $(input);
<span class="hljs-keyword">var</span> filterType = $input.attr(<span class="hljs-string">'data-filter-type'</span>);
<span class="hljs-keyword">var</span> fieldId = $input.attr(<span class="hljs-string">'data-filter-field'</span>);
<span class="hljs-keyword">var</span> filterIndex = <span class="hljs-built_in">parseInt</span>($input.attr(<span class="hljs-string">'data-filter-id'</span>), <span class="hljs-number">10</span>);
<span class="hljs-keyword">var</span> name = $input.attr(<span class="hljs-string">'name'</span>);
<span class="hljs-keyword">var</span> value = $input.val();
<span class="hljs-keyword">switch</span> (filterType) {
<span class="hljs-keyword">case</span> <span class="hljs-string">'term'</span>:
filters[filterIndex].term = value;
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> <span class="hljs-string">'range'</span>:
filters[filterIndex][name] = value;
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> <span class="hljs-string">'geo_distance'</span>:
<span class="hljs-keyword">if</span>(name === <span class="hljs-string">'distance'</span>) {
filters[filterIndex].distance = <span class="hljs-built_in">parseFloat</span>(value);
}
<span class="hljs-keyword">else</span> {
filters[filterIndex].point[name] = <span class="hljs-built_in">parseFloat</span>(value);
}
<span class="hljs-keyword">break</span>;
}
});
self.model.queryState.set({filters: filters, from: <span class="hljs-number">0</span>});
self.model.queryState.trigger(<span class="hljs-string">'change'</span>);
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,223 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>widget.pager.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>widget.pager.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;
my.Pager = Backbone.View.extend({
className: <span class="hljs-string">'recline-pager'</span>,
template: <span class="hljs-string">' \
&lt;div class="pagination"&gt; \
&lt;ul class="pagination"&gt; \
&lt;li class="prev action-pagination-update"&gt;&lt;a href="" class="btn btn-default"&gt;&amp;laquo;&lt;/a&gt;&lt;/li&gt; \
&lt;li class="page-range"&gt;&lt;a&gt;&lt;label for="from"&gt;From&lt;/label&gt;&lt;input id="from" name="from" type="text" value="{{from}}" /&gt; &amp;ndash; &lt;label for="to"&gt;To&lt;/label&gt;&lt;input id="to" name="to" type="text" value="{{to}}" /&gt; &lt;/a&gt;&lt;/li&gt; \
&lt;li class="next action-pagination-update"&gt;&lt;a href="" class="btn btn-default"&gt;&amp;raquo;&lt;/a&gt;&lt;/li&gt; \
&lt;/ul&gt; \
&lt;/div&gt; \
'</span>,
events: {
<span class="hljs-string">'click .action-pagination-update'</span>: <span class="hljs-string">'onPaginationUpdate'</span>,
<span class="hljs-string">'change input'</span>: <span class="hljs-string">'onFormSubmit'</span>
},
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.queryState, <span class="hljs-string">'change'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.render();
},
onFormSubmit: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>filter is 0-based; form is 1-based</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> formFrom = <span class="hljs-built_in">parseInt</span>(<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'input[name="from"]'</span>).val())-<span class="hljs-number">1</span>;
<span class="hljs-keyword">var</span> formTo = <span class="hljs-built_in">parseInt</span>(<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'input[name="to"]'</span>).val())-<span class="hljs-number">1</span>;
<span class="hljs-keyword">var</span> maxRecord = <span class="hljs-keyword">this</span>.model.recordCount-<span class="hljs-number">1</span>;
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.model.queryState.get(<span class="hljs-string">'from'</span>) != formFrom) { <span class="hljs-comment">// changed from; update from</span>
<span class="hljs-keyword">this</span>.model.queryState.set({from: <span class="hljs-built_in">Math</span>.min(maxRecord, <span class="hljs-built_in">Math</span>.max(formFrom, <span class="hljs-number">0</span>))});
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.model.queryState.get(<span class="hljs-string">'to'</span>) != formTo) { <span class="hljs-comment">// change to; update size</span>
<span class="hljs-keyword">var</span> to = <span class="hljs-built_in">Math</span>.min(maxRecord, <span class="hljs-built_in">Math</span>.max(formTo, <span class="hljs-number">0</span>));
<span class="hljs-keyword">this</span>.model.queryState.set({size: <span class="hljs-built_in">Math</span>.min(maxRecord+<span class="hljs-number">1</span>, <span class="hljs-built_in">Math</span>.max(to-formFrom+<span class="hljs-number">1</span>, <span class="hljs-number">1</span>))});
}
},
onPaginationUpdate: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $el = $(e.target);
<span class="hljs-keyword">var</span> newFrom = <span class="hljs-number">0</span>;
<span class="hljs-keyword">var</span> currFrom = <span class="hljs-keyword">this</span>.model.queryState.get(<span class="hljs-string">'from'</span>);
<span class="hljs-keyword">var</span> size = <span class="hljs-keyword">this</span>.model.queryState.get(<span class="hljs-string">'size'</span>);
<span class="hljs-keyword">var</span> updateQuery = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">if</span> ($el.parent().hasClass(<span class="hljs-string">'prev'</span>)) {
newFrom = <span class="hljs-built_in">Math</span>.max(currFrom - <span class="hljs-built_in">Math</span>.max(<span class="hljs-number">0</span>, size), <span class="hljs-number">0</span>);
updateQuery = newFrom != currFrom;
} <span class="hljs-keyword">else</span> {
newFrom = <span class="hljs-built_in">Math</span>.max(currFrom + size, <span class="hljs-number">0</span>);
updateQuery = (newFrom &lt; <span class="hljs-keyword">this</span>.model.recordCount);
}
<span class="hljs-keyword">if</span> (updateQuery) {
<span class="hljs-keyword">this</span>.model.queryState.set({from: newFrom});
}
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> tmplData = <span class="hljs-keyword">this</span>.model.toJSON();
<span class="hljs-keyword">var</span> from = <span class="hljs-built_in">parseInt</span>(<span class="hljs-keyword">this</span>.model.queryState.get(<span class="hljs-string">'from'</span>));
tmplData.from = from+<span class="hljs-number">1</span>;
tmplData.to = <span class="hljs-built_in">Math</span>.min(from+<span class="hljs-keyword">this</span>.model.queryState.get(<span class="hljs-string">'size'</span>), <span class="hljs-keyword">this</span>.model.recordCount);
<span class="hljs-keyword">var</span> templated = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(templated);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,184 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>widget.queryeditor.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>widget.queryeditor.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;
my.QueryEditor = Backbone.View.extend({
className: <span class="hljs-string">'recline-query-editor'</span>,
template: <span class="hljs-string">' \
&lt;form action="" method="GET" class="form-inline" role="form"&gt; \
&lt;div class="form-group"&gt; \
&lt;div class="input-group text-query"&gt; \
&lt;div class="input-group-addon"&gt; \
&lt;i class="glyphicon glyphicon-search"&gt;&lt;/i&gt; \
&lt;/div&gt; \
&lt;label for="q"&gt;Search&lt;/label&gt; \
&lt;input class="form-control search-query" type="text" id="q" name="q" value="{{q}}" placeholder="Search data ..."&gt; \
&lt;/div&gt; \
&lt;/div&gt; \
&lt;button type="submit" class="btn btn-default"&gt;Go &amp;raquo;&lt;/button&gt; \
&lt;/form&gt; \
'</span>,
events: {
<span class="hljs-string">'submit form'</span>: <span class="hljs-string">'onFormSubmit'</span>
},
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model, <span class="hljs-string">'change'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.render();
},
onFormSubmit: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> query = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.search-query'</span>).val();
<span class="hljs-keyword">this</span>.model.set({q: query});
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> tmplData = <span class="hljs-keyword">this</span>.model.toJSON();
<span class="hljs-keyword">var</span> templated = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(templated);
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,264 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>widget.valuefilter.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="backend.dataproxy.html">
backend.dataproxy.js
</a>
<a class="source" href="backend.memory.html">
backend.memory.js
</a>
<a class="source" href="ecma-fixes.html">
ecma-fixes.js
</a>
<a class="source" href="model.html">
model.js
</a>
<a class="source" href="view.flot.html">
view.flot.js
</a>
<a class="source" href="view.graph.html">
view.graph.js
</a>
<a class="source" href="view.grid.html">
view.grid.js
</a>
<a class="source" href="view.map.html">
view.map.js
</a>
<a class="source" href="view.multiview.html">
view.multiview.js
</a>
<a class="source" href="view.slickgrid.html">
view.slickgrid.js
</a>
<a class="source" href="view.timeline.html">
view.timeline.js
</a>
<a class="source" href="widget.facetviewer.html">
widget.facetviewer.js
</a>
<a class="source" href="widget.fields.html">
widget.fields.js
</a>
<a class="source" href="widget.filtereditor.html">
widget.filtereditor.js
</a>
<a class="source" href="widget.pager.html">
widget.pager.js
</a>
<a class="source" href="widget.queryeditor.html">
widget.queryeditor.js
</a>
<a class="source" href="widget.valuefilter.html">
widget.valuefilter.js
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>widget.valuefilter.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span>
<span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
<span class="hljs-pi"> "use strict"</span>;
my.ValueFilter = Backbone.View.extend({
className: <span class="hljs-string">'recline-filter-editor well'</span>,
template: <span class="hljs-string">' \
&lt;div class="filters"&gt; \
&lt;h3&gt;Filters&lt;/h3&gt; \
&lt;button class="btn js-add-filter add-filter"&gt;Add filter&lt;/button&gt; \
&lt;form class="form-stacked js-add" style="display: none;"&gt; \
&lt;fieldset&gt; \
&lt;label&gt;Field&lt;/label&gt; \
&lt;select class="fields form-control"&gt; \
{{#fields}} \
&lt;option value="{{id}}"&gt;{{label}}&lt;/option&gt; \
{{/fields}} \
&lt;/select&gt; \
&lt;button type="submit" class="btn"&gt;Add&lt;/button&gt; \
&lt;/fieldset&gt; \
&lt;/form&gt; \
&lt;form class="form-stacked js-edit"&gt; \
{{#filters}} \
{{{filterRender}}} \
{{/filters}} \
{{#filters.length}} \
&lt;button type="submit" class="btn update-filter"&gt;Update&lt;/button&gt; \
{{/filters.length}} \
&lt;/form&gt; \
&lt;/div&gt; \
'</span>,
filterTemplates: {
term: <span class="hljs-string">' \
&lt;div class="filter-{{type}} filter"&gt; \
&lt;fieldset&gt; \
{{field}} \
&lt;a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}"&gt;&amp;times;&lt;/a&gt; \
&lt;input type="text" value="{{term}}" name="term" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /&gt; \
&lt;/fieldset&gt; \
&lt;/div&gt; \
'</span>
},
events: {
<span class="hljs-string">'click .js-remove-filter'</span>: <span class="hljs-string">'onRemoveFilter'</span>,
<span class="hljs-string">'click .js-add-filter'</span>: <span class="hljs-string">'onAddFilterShow'</span>,
<span class="hljs-string">'submit form.js-edit'</span>: <span class="hljs-string">'onTermFiltersUpdate'</span>,
<span class="hljs-string">'submit form.js-add'</span>: <span class="hljs-string">'onAddFilter'</span>
},
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
_.bindAll(<span class="hljs-keyword">this</span>, <span class="hljs-string">'render'</span>);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.fields, <span class="hljs-string">'all'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.queryState, <span class="hljs-string">'change change:filters:new-blank'</span>, <span class="hljs-keyword">this</span>.render);
<span class="hljs-keyword">this</span>.render();
},
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> tmplData = $.extend(<span class="hljs-literal">true</span>, {}, <span class="hljs-keyword">this</span>.model.queryState.toJSON());</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>we will use idx in list as the id …</p>
</div>
<div class="content"><div class='highlight'><pre> tmplData.filters = _.map(tmplData.filters, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(filter, idx)</span> </span>{
filter.id = idx;
<span class="hljs-keyword">return</span> filter;
});
tmplData.fields = <span class="hljs-keyword">this</span>.model.fields.toJSON();
tmplData.filterRender = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> Mustache.render(self.filterTemplates.term, <span class="hljs-keyword">this</span>);
};
<span class="hljs-keyword">var</span> out = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
<span class="hljs-keyword">this</span>.$el.html(out);
},
updateFilter: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(input)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> filters = self.model.queryState.get(<span class="hljs-string">'filters'</span>);
<span class="hljs-keyword">var</span> $input = $(input);
<span class="hljs-keyword">var</span> filterIndex = <span class="hljs-built_in">parseInt</span>($input.attr(<span class="hljs-string">'data-filter-id'</span>), <span class="hljs-number">10</span>);
<span class="hljs-keyword">var</span> value = $input.val();
filters[filterIndex].term = value;
},
onAddFilterShow: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $target = $(e.target);
$target.hide();
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'form.js-add'</span>).show();
},
onAddFilter: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $target = $(e.target);
$target.hide();
<span class="hljs-keyword">var</span> field = $target.find(<span class="hljs-string">'select.fields'</span>).val();
<span class="hljs-keyword">this</span>.model.queryState.addFilter({type: <span class="hljs-string">'term'</span>, field: field});
},
onRemoveFilter: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
e.preventDefault();
<span class="hljs-keyword">var</span> $target = $(e.target);
<span class="hljs-keyword">var</span> filterId = $target.attr(<span class="hljs-string">'data-filter-id'</span>);
<span class="hljs-keyword">this</span>.model.queryState.removeFilter(filterId);
},
onTermFiltersUpdate: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
e.preventDefault();
<span class="hljs-keyword">var</span> filters = self.model.queryState.get(<span class="hljs-string">'filters'</span>);
<span class="hljs-keyword">var</span> $form = $(e.target);
_.each($form.find(<span class="hljs-string">'input'</span>), <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(input)</span> </span>{
self.updateFilter(input);
});
self.model.queryState.set({filters: filters, from: <span class="hljs-number">0</span>});
self.model.queryState.trigger(<span class="hljs-string">'change'</span>);
}
});
})(jQuery, recline.View);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,205 +0,0 @@
---
layout: container
title: Loading data from different sources using Backends - Tutorial
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Loading data from different sources using Backends
<br />
<small>These set of examples will show you how you can load data from different
sources such as Google Docs or the DataHub using Recline</small>
</h1>
</div>
## Overview
Backends connect Recline Datasets to data from a specific 'Backend' data
source.
They provide methods for loading and saving Datasets and individuals
Documents as well as for bulk loading via a query API and doing bulk transforms
on the backend.
Backends come in 2 flavours:
* Loader backends - only implement fetch method. The data is then cached in a
Memory.Store on the Dataset and interacted with there. This is best for
sources which just allow you to load data or where you want to load the data
once and work with it locally.
* Store backends - these support fetch, query and, if write-enabled, save.
These are suited to cases where the source datastore contains a lot of data
(infeasible to load locally - for examples a million rows) or where the
backend has, for example, query capabilities you want to take advantage of.
### Instantiation and Use
You can use a backend directly e.g.
{% highlight javascript %}
var backend = recline.Backend.ElasticSearch.fetch({url: ...});
{% endhighlight %}
But more usually the backend will be created or loaded for you by Recline and
all you need is provide the identifier for that Backend e.g.
{% highlight javascript %}
var dataset = recline.Model.Dataset({
backend: 'backend-identifier'
});
{% endhighlight %}
<div class="alert alert-info">
<p><strong>Backend identifiers</strong>
How do you know the backend identifier for a given Backend? It's just the name
of the 'class' in recline.Backend module (but case-insensitive). E.g.
recline.Backend.ElasticSearch can be identified as 'ElasticSearch' or
'elasticsearch'.</p>
</div>
## What Backends are available from Recline?
{% include backend-list.html %}
**Backend you'd like to see not available?** It's easy to write your own
&ndash; see the <a href="backends.html">Backend reference docs</a> for details
of the required API.
## Preparing your app
This is as per the [quickstart](tutorial-views.html) but the set of files is
much more limited if you are just using a Backend. Specifically:
{% highlight html %}
<!-- 3rd party dependencies -->
<script type="text/javascript" src="vendor/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript" src="vendor/underscore/1.1.6/underscore.js"></script>
<script type="text/javascript" src="vendor/backbone/0.5.1/backbone.js"></script>
<!-- include the backend code you need e.g. here for csv -->
<script type="text/javascript" src="http://okfnlabs.org/csv.js/csv.js"></script>
<!-- Or you can just include all of recline. -->
<script type="text/javascript" src="dist/recline.js"></script>
{% endhighlight %}
## Loading Data from Google Docs
We will be using the [following Google
Doc](https://docs.google.com/spreadsheet/ccc?key=0Aon3JiuouxLUdGZPaUZsMjBxeGhfOWRlWm85MmV0UUE#gid=0).
For Recline to be able to access a Google Spreadsheet it **must** have been
'Published to the Web' (enabled via File -> Publish to the Web menu).
{% highlight javascript %}
// include the Recline backend for Google Docs
<script type="text/javascript" src="http://okfnlabs.org/recline.backend.gdocs/backend.gdocs.js"></script>
{% include example-backends-gdocs.js %}
{% endhighlight %}
### Result
<div id="my-gdocs" class="doc-ex-rendered">&nbsp;</div>
<script type="text/javascript" src="http://okfnlabs.org/recline.backend.gdocs/backend.gdocs.js">&nbsp;</script>
<script type="text/javascript">
{% include example-backends-gdocs.js %}
</script>
## Loading Data from ElasticSearch
Recline supports ElasticSearch as a full read/write/query backend via the
[ElasticSearch.js library][esjs]. See the library for examples.
[esjs]: https://github.com/okfn/elasticsearch.js
## Loading data from CSV files
For loading data from CSV files there are 3 cases:
1. CSV is online but on same domain or supporting CORS (S3 and Google Storage support CORS!) -- we can then load using AJAX (as no problems with same origin policy)
2. CSV is on local disk -- if your browser supports HTML5 File API we can load the CSV file off disk
3. CSV is online but not on same domain -- use DataProxy (see below)
In all cases we'll need to have loaded the Recline CSV backend (for your own
app you'll probably want this locally):
{% highlight html %}
<script type="text/javascript" src="http://okfnlabs.org/csv.js/csv.js"></script>
{% endhighlight %}
### Local online CSV file
Let's start with first case: loading a "local" online CSV file. We'll be using this [example file]({{page.root}}/demos/data/sample.csv).
{% highlight javascript %}
{% include example-backends-online-csv.js %}
{% endhighlight %}
#### Result
<div id="my-online-csv" class="doc-ex-rendered">&nbsp;</div>
<script type="text/javascript">
{% include example-backends-online-csv.js %}
</script>
### CSV file on disk
This requires your browser to support the HTML5 file API. Suppose we have a file input like:
<input type="file" class="my-file-input" />
Then we can load the file into a Recline Dataset as follows:
{% highlight javascript %}
{% include example-backends-csv-disk.js %}
{% endhighlight %}
#### Try it out!
Try it out by clicking on the file input above, selecting a CSV file and seeing what happens.
<div id="my-csv-disk" class="doc-ex-rendered">&nbsp;</div>
<script type="text/javascript">
{% include example-backends-csv-disk.js %}
</script>
## Loading data from CSV and Excel files online using DataProxy
The [DataProxy](http://github.com/okfn/dataproxy) is a web-service run by the Open Knowledge Foundation that converts CSV and Excel files to JSON. It has a convenient JSON-p-able API which means we can use it to load data from online CSV and Excel into Recline Datasets.
Recline ships with a simple DataProxy "backend" that takes care of fetching data from the DataProxy source.
The main limitation of the DataProxy is that it can only handle Excel files up to a certain size (5mb) and that as we must use JSONP to access it error information can be limited.
{% highlight javascript %}
{% include example-backends-dataproxy.js %}
{% endhighlight %}
### Result
<div id="my-dataproxy" class="doc-ex-rendered">&nbsp;</div>
<script type="text/javascript">
{% include example-backends-dataproxy.js %}
</script>
### Customizing the timeout
As we must use JSONP in this backend we have the problem that if DataProxy errors (e.g. 500) this won't be picked up. To deal with this and prevent the case where the request never finishes We have a timeout on the request after which the Backend sends back an error stating that request timed out.
You can customize the length of this timeout by setting the following constant:
{% highlight javascript %}
// Customize the timeout (in milliseconds) - default is 5000
recline.Backend.DataProxy.timeout = 10000;
{% endhighlight %}

View File

@@ -1,55 +0,0 @@
---
layout: container
title: Tutorial - Dataset Basics - Events
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Dataset Basics - Events
</h1>
</div>
## Preparations
See <a href="{{page.root}}/docs/tutorial-basics.html">first Dataset basics tutorial</a> for getting setup and initializing Dataset.
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
</script>
## Listening for Events
Often you'll want to listen to events on a Dataset and its associated objects. This is easy to do thanks to the use of Backbone model objects which have a [standard set of events](http://backbonejs.org/#FAQ-events).
Here's an example to illustrate:
{% highlight javascript %}
{% include tutorial-basics-ex-events.js %}
{% endhighlight %}
<div class="ex-events well">&nbsp;</div>
<script type="text/javascript">
$('.ex-events').html('');
{% include tutorial-basics-ex-events.js %}
</script>
Here's a summary of the main objects and their events:
* Dataset:
* Standard Backbone events for changes to attributes (note that this will **not** include changes to records)
* *query:start / query:end* called at start and completion of a query
* Dataset.records: Backbone.Collection of "current" records (i.e. those resulting from latest query) with standard Backbone set of events: *add, reset, remove*
* Dataset.queryState: queryState is a Query object with standard Backbone Model set of events
* Dataset.fields: Backbone Collection of Fields.

View File

@@ -1,70 +0,0 @@
---
layout: container
title: Tutorial - Dataset Basics
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Dataset Basics - Querying
</h1>
</div>
## Preparations
See <a href="{{page.root}}/docs/tutorial-basics.html">first Dataset basics tutorial</a> for getting setup and initializing a Dataset.
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
</script>
## Querying
The basic thing we want to do with Datasets is query and filter them. This is
very easy to do:
{% highlight javascript %}
{% include tutorial-basics-ex-2.js %}
{% endhighlight %}
This results in the following. Note how recordCount is now 3 (the total number
of records matched by the query) but that records only contains 2 records as we
restricted number of returned records using the size attribute.
<div class="ex-2 well">&nbsp;</div>
<script type="text/javascript">
$('.ex-2').html('');
{% include tutorial-basics-ex-2.js %}
</script>
## Filtering
A simple unstructured query like the one provided above searches all fieldsfor the value provided.
Often you want to "filter" results more precisely, for example by specifying a specific value in a specific field. To do this we use "filters".
{% highlight javascript %}
var query = new recline.Model.Query();
query.addFilter({type: 'term', field: 2});
dataset.query(query);
{% endhighlight %}
## QueryState
The last run query is stored as a <a href="models.html#query">Query
instance</a> in the `queryState` attribute of the Dataset object. Modifying
`queryState` will also resulting in a query being run. This is useful when
building views that want to display or manage the query state (see, for
example, <a href="src/widget.queryeditor.html">Query Editor</a> or <a
href="src/widget.filtereditor.html">Filter Editor</a> widgets).
## Full Details of the Query Language
Full details of the <a href="models.html#query">query structure and its options
can be found in the reference documentation</a>.

View File

@@ -1,152 +0,0 @@
---
layout: container
title: Tutorial - Dataset Basics
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Getting Started with Datasets
<br />
<small>This step-by-step tutorial will quickly get you started withthe central Recline object: a Dataset</small>
</h1>
</div>
## Preparations
1. [Download ReclineJS]({{page.root}}download.html) and relevant dependencies.
2. Include the core dependencies for the Dataset model
{% highlight html %}<!-- 3rd party dependencies -->
<script type="text/javascript" src="vendor/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript" src="vendor/underscore/1.1.6/underscore.js"></script>
<script type="text/javascript" src="vendor/backbone/0.5.1/backbone.js"></script>
<!-- Recline -->
<script type="text/javascript" src="dist/recline.js"></script>{% endhighlight %}
## Creating a Dataset
Here's the example data We are going to work with:
{% highlight javascript %}
{% include data.js %}
{% endhighlight %}
In this data we have 6 records / rows. Each record is a javascript object
containing keys and values (values can be 'simple' e.g. a string or float or arrays or hashes - e.g. the geo value here).
<div class="alert alert-info">In this tutorial we are creating datasets with
"local" JS data. However, Recline has a variety of Backends that make it easy
to create Datasets from a variety of online sources and local sources including
Google Spreadsheets, CSV files, etc. See the <a
href="tutorial-backends.html">Backend tutorial</a> for more.</div>
We can now create a recline Dataset object from this raw data:
{% highlight javascript %}
var dataset = new recline.Model.Dataset({
records: data
});
{% endhighlight %}
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
</script>
## A Dataset and its Records
Now that we have created a Dataset, we can use it.
For example, let's display some information about the Dataset and its records using some of the key Dataset attributes: `recordCount` and `records`.
{% highlight javascript %}
{% include tutorial-basics-ex-1.js %}
{% endhighlight %}
Here's the output:
<div class="ex-1 well">&nbsp;</div>
<script type="text/javascript">
$('.ex-1').html('');
{% include tutorial-basics-ex-1.js %}
</script>
### Records
`Dataset.records` is a Backbone Collection of `Record`s resutling from latest query. This need not (and usually isn't) **all** the records in this Dataset since the latest query need not have matched all records.
<div class="alert alert-info">
Note that on initialization, a Dataset automatically queries for the first 100 records so this is what will usually be available in th <code>records</code> attribute. If you did want all records loaded into <code>records</code> at the start just requery after fetch has completed:
{% highlight javascript %}
// for the async case need to put inside of done
dataset.fetch().done(function() {
dataset.query({size: dataset.recordCount});
});
{% endhighlight %}
</div>
As a Backbone Collection it supports all the standard Backbone collection functionality including methods like `each` and `filter`:
{% highlight javascript %}
dataset.records.each(function(record) {
console.log(record.get('x') * 2);
});
var filtered = dataset.records.filter(function(record) {
return (record.get('z') > 4 && record.get('z') < 18);
});
// get all the values for a given attribute/field/column
var xvalues = dataset.records.pluck('x');
// calls toJSON on all records at once
dataset.records.toJSON();
{% endhighlight %}
<div class="alert alert-info">Want to know more about Dataset and Records? Check out the <a href="models.html">reference documentation</a></div>
## Fields
In addition to Records, a Dataset has <a href="models.html#field">Fields</a> stored in the `fields` attribute. Fields provide information about the fields/columns in the Dataset, for example their id (key name in record), label, type etc.
The Dataset's fields will be automatically computed from records or provided by the backend but they can also be explicitly provided and configured. Let's take a look at the fields on the dataset at present using the following code:
{% highlight javascript %}
{% include tutorial-basics-ex-fields.js %}
{% endhighlight %}
Running this results in the following:
<div class="ex-fields well">&nbsp;</div>
<script type="text/javascript">
$('.ex-fields').html('');
{% include tutorial-basics-ex-fields.js %}
</script>
As can be seen all fields have the default type of 'string'.
As you may have noticed above the last geo attribute of the dataset just rendered as `[object Object]`. This is because the Dataset is treating that field value as a string. Let's now take a look at the Dataset fields in more detail.
Let's change the geo field to have type geo\_point and see what affect that has on displaying of the dataset (for good measure we'll also set the label):
{% highlight javascript %}
{% include tutorial-basics-ex-fields-2.js %}
{% endhighlight %}
<div class="ex-fields-2 well">&nbsp;</div>
<script type="text/javascript">
$('.ex-fields-2').html('');
{% include tutorial-basics-ex-fields-2.js %}
</script>
As can be seen the rendering of the field has changed. This is because the `summary` method uses the Record.getFieldValue function which in turn renders a record field using the Field's renderer function. This function varies depending on the type and can also be customized (see the <a href="models.html#field">Field documentation</a>).

View File

@@ -1,52 +0,0 @@
---
layout: container
title: Grids - Advanced use of grids in Recline - Tutorial
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Doing More with Grids
<br />
<small>This tutorial goes beyond the <a href="tutorial-views.html">basic
views tutorial</a> and shows you how to do more with grids</small>
</h1>
</div>
### How much can I do with a simple grid view
### Benefits of SlickGrid
What does Recline give you out of the box, what does SlickGrid have built in and how to use it (reference to stuff below).
### Preparing your page
See the instructions in the [basic views tutorial](tutorial-views.html).
### Creating a Dataset
Just like in the main tutorial, here's some example data We are going to work with:
{% highlight javascript %}
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
{% endhighlight %}
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
</script>
### Accessing SlickGrid features
Show how we can customize SlickGrid grid "normally" - i.e. you can get access to underlying grid and tweak it as you want.
Suggest we demonstrate using this example: https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example-plugin-headermenu.html
Idea here is: we don't want to mimic all that slickgrid can do through recline interface - just let people do it directly themselves ...

View File

@@ -1,131 +0,0 @@
---
layout: container
title: Maps - Customizing Maps in Recline - Tutorial
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Doing More with the Map View
<br />
<small>This tutorial goes beyond the <a href="tutorial-views.html">basic
views tutorial</a> and shows you how to do more with maps</small>
</h1>
</div>
### Preparing your page
See the instructions in the [basic views tutorial](tutorial-views.html).
### Creating a Dataset
Just like in the main tutorial, here's some example data We are going to work with:
{% highlight javascript %}
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
{% endhighlight %}
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
</script>
### General Pointers
Check out the <a href="{{page.root}}/docs/src/view.map.html">Map reference
(source) docs</a>. In particular this has details of the various state options.
In addition, remember that Recline's map view is just a relatively lightweight
wrapper around Leaflet. This means that pretty much anything you can do with
Leaflet you can do with Recline's map. Specifically a `recline.View.Map`
instance has the following attributes exposed:
map: the Leaflet map (L.Map)
features: Leaflet GeoJSON layer (L.GeoJSON) containing all the features
(Recline converts all records in a dataset that yield geospatial info to a
GeoJSON feature and adds it to the features layer).
### Customizing the infobox
The default infobox just shows all of the dataset attributes. Usually you'll
want something a bit nicer. All you need to do is override the infobox
function. For example, in our case let's make a nicer title and only show some
data.
{% highlight javascript %}
{% include tutorial-maps-infobox.js %}
{% endhighlight %}
<div id="map-infobox">&nbsp;</div>
<script type="text/javascript">
{% include tutorial-maps-infobox.js %}
</script>
### Customizing the marker
We're going to show how to replace the default marker with a circular marker.
Even more exciting, we'll show how to have the marker size vary with an
attribute of our data. We do the customization by via over-riding the
pointToLayer function:
{% highlight javascript %}
{% include tutorial-maps-customize.js %}
{% endhighlight %}
<div id="map-customize">&nbsp;</div>
<script type="text/javascript">
{% include tutorial-maps-customize.js %}
</script>
### Customing features (which aren't points)
Leaflet treats points and features differently. To customize features that
aren't point we will need to bind to the feature layers featureparse event. As
the feature layer can get re-rendered you don't do this directly but rather set
the featureparse function on the recline view. For example, for classic popup
behaviour:
{% highlight javascript %}
view.featureparse = function (e) {
if (e.properties && e.properties.popupContent) {
e.layer.bindPopup(e.properties.popupContent);
}
};
{% endhighlight %}
### Turning on clustering
You can turn on clustering of markers by setting the cluster option:
var map = new recline.View.Map({
model: dataset
state: {
cluster: true;
}
});
You could also enable marker clustering only if you have more than a
certain number of markers. Here's an example:
// var map is recline.View.Map instance
// marker cluster threshold
var threshold = 65;
// enable clustering if there is a large number of markers
var countAfter = 0;
map.features.eachLayer(function(){countAfter++;});
if (countAfter > threshold) {
// note the map will auto-redraw when you change state!
map.state.set({cluster: true});
}

View File

@@ -1,233 +0,0 @@
---
layout: container
title: Library - Multiview Tutorial
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Multiview Tutorial
<br />
<small>This tutorial will quickly get you started with Recline Multiview</small>
</h1>
</div>
<div class="alert alert-info">
The <strong>full</strong> source code along with all dependencies for the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-multiview-demo">this GitHub repository</a>. Do not try to assemble a working example from the code snippets in this page! See it in action via <a href="http://mattfullerton.github.io/recline-view-multiview-demo/">GitHub Pages</a>.
The code is almost identical to that used for the <a href="../demos/multiview/">site demo</a>, with the advantage of the code being separated out of the main recline website. You can also see Multiview in action in many <a href="http://www.ckan.org">CKAN</a>-based data catalogs (resource views) and in the <a href="http://explorer.okfnlabs.org">OKFN Labs DataDeck</a></div>
### Multiview
Multiview, as its name suggests, combines multiple [Recline views](views.html) into one visualization. The different views are synced to one dataset. The [technical documentation for Multiview](src/view.multiview.html) details the nuts and bolts.
When building a Multiview from scratch, it is advised to start by getting each individual view to work satisfactorily before combining into a Multiview, to aid debugging.
### Preparing your page
Before writing any code with Recline, you need to do the following preparation steps on your page:
* [Download ReclineJS]({{page.root}}download.html) (downloading the master, developer code is recommended as this example is based on that and all dependencies should be available) or the <a href="https://github.com/mattfullerton/recline-view-multiview-demo/archive/gh-pages.zip">all-in-one demo code</a>.
* Include the Multiview CSS as well as the CSS for each view in the head section of your document, as well as any 3rd party CSS for each view e.g.:
{% highlight html %}
<!-- you do not have to use bootstrap but we use it by default -->
<link rel="stylesheet" href="vendor/bootstrap/3.2.0/css/bootstrap.css">
<!-- vendor css -->
<link href="vendor/leaflet/0.7.3/leaflet.css" rel="stylesheet">
<link href="vendor/leaflet.markercluster/MarkerCluster.css" rel="stylesheet">
<link href="vendor/leaflet.markercluster/MarkerCluster.Default.css" rel=
"stylesheet">
<link rel="stylesheet" href="vendor/slickgrid/2.2/slick.grid.css">
<!-- recline css -->
<link href="css/map.css" rel="stylesheet">
<link href="css/multiview.css" rel="stylesheet">
<link href="css/slickgrid.css"rel="stylesheet">
<link href="css/flot.css" rel="stylesheet">
{% endhighlight %}
* Include the relevant Javascript files somewhere on the page (preferably before body close tag). You will need to include any necessary Javascript dependencies for each view as well, e.g.:
{% highlight html %}
<!-- Vendor JS - general dependencies -->
<script src="vendor/jquery/1.7.1/jquery.js" type="text/javascript"></script>
<script src="vendor/underscore/1.4.4/underscore.js" type="text/javascript"></script>
<script src="vendor/backbone/1.0.0/backbone.js" type="text/javascript"></script>
<script src="vendor/mustache/0.5.0-dev/mustache.js" type="text/javascript"></script>
<script src="vendor/bootstrap/3.2.0/js/bootstrap.js" type="text/javascript"></script>
<!-- Vendor JS - view dependencies -->
<script src="vendor/leaflet/0.4.4/leaflet.js" type="text/javascript"></script>
<script src="vendor/leaflet.markercluster/leaflet.markercluster.js" type="text/javascript"></script>
<script type="text/javascript" src="vendor/flot/jquery.flot.js"></script>
<script type="text/javascript" src="vendor/flot/jquery.flot.time.js"></script>
<script type="text/javascript" src="vendor/moment/2.0.0/moment.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/jquery-ui-1.8.16.custom.min.js"></script>
<script src="vendor/slickgrid/2.2/jquery.event.drag-2.2.js"></script>
<script src="vendor/slickgrid/2.2/jquery.event.drop-2.2.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/slick.core.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/slick.formatters.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/slick.editors.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/slick.grid.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/plugins/slick.rowselectionmodel.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/plugins/slick.rowmovemanager.js"></script>
<!-- Recline JS (combined distribution, all views) -->
<script src="dist/recline.js" type="text/javascript"></script>
{% endhighlight %}
### Creating a Dataset
Here's the function to create an example dataset we are going to work with:
{% highlight javascript %}
function createDemoDataset() {
var dataset = new recline.Model.Dataset({
records: [
{id: 0, date: '2011-01-01', x: 1, y: 2, z: 3, country: 'DE', sometext: 'first', lat:52.56, lon:13.40},
{id: 1, date: '2011-02-02', x: 2, y: 4, z: 24, country: 'UK', sometext: 'second', lat:54.97, lon:-1.60},
{id: 2, date: '2011-03-03', x: 3, y: 6, z: 9, country: 'US', sometext: 'third', lat:40.00, lon:-75.5},
{id: 3, date: '2011-04-04', x: 4, y: 8, z: 6, country: 'UK', sometext: 'fourth', lat:57.27, lon:-6.20},
{id: 4, date: '2011-05-04', x: 5, y: 10, z: 15, country: 'UK', sometext: 'fifth', lat:51.58, lon:0},
{id: 5, date: '2011-06-02', x: 6, y: 12, z: 18, country: 'DE', sometext: 'sixth', lat:51.04, lon:7.9}
],
// let's be really explicit about fields
// Plus take opportunity to set date to be a date field and set some labels
fields: [
{id: 'id'},
{id: 'date', type: 'date'},
{id: 'x', type: 'number'},
{id: 'y', type: 'number'},
{id: 'z', type: 'number'},
{id: 'country', 'label': 'Country'},
{id: 'sometext', 'label': 'Some text'},
{id: 'lat'},
{id: 'lon'}
]
});
return dataset;
}
{% endhighlight %}
In this data we have 6 documents / rows. Each document is a javascript object
containing keys and values (note that all values here are 'simple' but there is
no reason you cannot have objects as values allowing you to nest data.
### Setting up the Multiview
To create a Multiview, we first create each view that we want to include, and include these in an array. A function to do everything for SlickGrid, Graph and Map views is shown below:
{% highlight javascript %}
var createMultiView = function(dataset, state) {
// remove existing multiview if present
var reload = false;
if (window.multiView) {
window.multiView.remove();
window.multiView = null;
reload = true;
}
var $el = $('<div />');
$el.appendTo(window.explorerDiv);
// customize the subviews for the MultiView
var views = [
{
id: 'grid',
label: 'Grid',
view: new recline.View.SlickGrid({
model: dataset,
state: {
gridOptions: {
editable: true,
// Enable support for row add
enabledAddRow: true,
// Enable support for row delete
enabledDelRow: true,
// Enable support for row ReOrder
enableReOrderRow:true,
autoEdit: false,
enableCellNavigation: true
},
columnsEditor: [
{ column: 'date', editor: Slick.Editors.Date },
{ column: 'sometext', editor: Slick.Editors.Text }
]
}
})
},
{
id: 'graph',
label: 'Graph',
view: new recline.View.Graph({
model: dataset
})
},
{
id: 'map',
label: 'Map',
view: new recline.View.Map({
model: dataset
})
}
];
var multiView = new recline.View.MultiView({
model: dataset,
el: $el,
state: state,
views: views
});
return multiView;
}
{% endhighlight %}
To tie it all together:
{% highlight javascript %}
jQuery(function($) {
window.multiView = null;
window.explorerDiv = $('.data-explorer-here');
// create the demo dataset
var dataset = createDemoDataset();
// now create the multiview
// this is rather more elaborate than the minimum as we configure the
// MultiView in various ways (see function below)
window.multiview = createMultiView(dataset);
// last, we'll demonstrate binding to changes in the dataset
// this will print out a summary of each change onto the page in the
// changelog section
dataset.records.bind('all', function(name, obj) {
var $info = $('<div />');
$info.html(name + ': ' + JSON.stringify(obj.toJSON()));
$('.changelog').append($info);
$('.changelog').show();
});
});
{% endhighlight %}
The HTML is very simple:
{% highlight html %}
<div class="container">
<style type="text/css">
.recline-slickgrid {
height: 300px;
}
.changelog {
display: none;
border-bottom: 1px solid #ccc;
margin-bottom: 10px;
}
</style>
<div class="changelog">
<h3>Changes</h3>
</div>
<div class="data-explorer-here"></div>
<div style="clear: both;"></div>
</div>
{% endhighlight %}

View File

@@ -1,50 +0,0 @@
---
layout: container
title: Timelines - Advanced use of timelines in Recline - Tutorial
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Doing More with Timelines
<br />
<small>This tutorial goes beyond the <a href="tutorial-views.html">basic
views tutorial</a> and shows you how to do more with timelines</small>
</h1>
</div>
### Preparing your page
See the instructions in the [basic views tutorial](tutorial-views.html).
### Creating a Dataset
Just like in the main tutorial, here's some example data We are going to work with:
{% highlight javascript %}
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
{% endhighlight %}
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
</script>
### Underlying library and Recline extensions
### Handling dates
### Customizing the rendering

View File

@@ -1,316 +0,0 @@
---
layout: container
title: Library - Example - Quickstart
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Views Tutorial
<br />
<small>This step-by-step tutorial will quickly get you started with Recline basics, including creating a dataset from local data and setting up a grid, graph, map and timeline to display it.</small>
</h1>
</div>
### Views
Views display Recline datasets in different ways. This page covers the interesting built-in views. For a full list of views including extensions outside of the Recline.js core, see the [list of currently available views]({{page.root}}docs/views.html#dataset-views-currently-available).
### Preparing your page
Before writing any code with Recline, you need to do the following preparation steps on your page:
* [Download ReclineJS]({{page.root}}download.html) and relevant dependencies.
* Include the relevant CSS in the head section of your document (for view-specific CSS files, see below):
{% highlight html %}
<!-- you do not have to use bootstrap but we use it by default -->
<link rel="stylesheet" href="vendor/bootstrap/3.2.0/css/bootstrap.css" />
{% endhighlight %}
* Include the relevant Javascript files somewhere on the page (preferably before body close tag; for view-specific Javascript dependencies, see below):
{% highlight html %}<!-- 3rd party dependencies -->
<script type="text/javascript" src="vendor/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript" src="vendor/underscore/1.4.4/underscore.js"></script>
<script type="text/javascript" src="vendor/backbone/1.0.0/backbone.js"></script>
<script type="text/javascript" src="vendor/mustache/0.5.0-dev/mustache.js"></script>
<script type="text/javascript" src="vendor/bootstrap/3.2.0/js/bootstrap.js"></script>
<!-- note that we could include individual components rather than whole of recline e.g.
<script type="text/javascript" src="src/model.js"></script>
<script type="text/javascript" src="src/backend.memory.js"></script>
<script type="text/javascript" src="src/view-grid.js"></script>
-->
<script type="text/javascript" src="dist/recline.js"></script>{% endhighlight %}
You're now ready to start working with Recline.
### Creating a Dataset
Here's some example data we are going to work with:
{% highlight javascript %}
{% include data.js %}
{% endhighlight %}
In this data we have 6 documents / rows. Each document is a javascript object
containing keys and values (note that all values here are 'simple' but there is
no reason you cannot have objects as values allowing you to nest data.
We can now create a recline Dataset object (and memory backend) from this raw data:
{% highlight javascript %}
var dataset = new recline.Model.Dataset({
records: data
});
//Depending on the view, it may be important to set the date type
dataset.fields.models[1].attributes.type = 'date';
{% endhighlight %}
### Setting up the Grid
<div class="alert alert-info">
The source code along with all dependencies for the grid part of the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-slickgrid-demo">this GitHub repository</a>. See it in action via <a href="http://mattfullerton.github.io/recline-view-slickgrid-demo/">GitHub Pages</a>.
Although it's not demonstrated here, you can also use the simpler Grid view without SlickGrid. Source code along with all dependencies for that can be found at <a href="https://github.com/mattfullerton/recline-view-grid-demo">this GitHub repository</a>. Demo on <a href="http://mattfullerton.github.io/recline-view-grid-demo/">GitHub Pages</a>.
</div>
Let's create a data grid view to display the dataset we have just created. We're going to use the SlickGrid-based grid so we need the following CSS and JS dependencies in addition to those above:
{% highlight html %}
<link rel="stylesheet" href="css/grid.css" />
<link rel="stylesheet" href="css/slickgrid.css">
<link rel="stylesheet" href="vendor/slickgrid/2.2/slick.grid.css">
<!-- vendor -->
<script type="text/javascript" src="vendor/slickgrid/2.2/jquery-ui-1.8.16.custom.min.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/jquery.event.drag-2.2.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/slick.core.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/slick.grid.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/slick.formatters.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/slick.editors.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/plugins/slick.rowselectionmodel.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.2/plugins/slick.rowmovemanager.js"></script>
<!-- Recline (only needed when NOT including the combined JS file as shown above) -->
<script type="text/javascript" src="src/view.slickgrid.js"></script>
{% endhighlight %}
Now, let's create an HTML element to for the Grid:
{% highlight html %}
<div id="mygrid" style="height: 400px"></div>
{% endhighlight %}
Now let's set up the Grid:
{% highlight javascript %}
var $el = $('#mygrid');
var grid = new recline.View.SlickGrid({
model: dataset,
el: $el
});
grid.visible = true;
grid.render();
{% endhighlight %}
And hey presto:
<div id="mygrid" class="recline-read-only" style="margin-bottom: 30px; height: 200px;">&nbsp;</div>
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
var $el = $('#mygrid');
var grid = new recline.View.SlickGrid({
model: dataset,
el: $el
});
grid.visible = true;
grid.render();
</script>
### Creating a Graph
<div class="alert alert-info">
The source code along with all dependencies for the graph part of the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-graph-demo">this GitHub repository</a>. See it in action via <a href="http://mattfullerton.github.io/recline-view-graph-demo/">GitHub Pages</a>.
</div>
Let's create a graph view to display a line graph for this dataset.
First, add the additional dependencies for this view. These are the Flot
library and the Recline Flot Graph view:
{% highlight html %}
<link rel="stylesheet" href="css/flot.css">
<!-- javascript -->
<!--[if lte IE 8]>
<script language="javascript" type="text/javascript" src="vendor/flot/excanvas.min.js"></script>
<![endif]-->
<!-- you only need moment when you have datetime data -->
<script type="text/javascript" src="vendor/moment/2.0.0/moment.js"></script>
<script type="text/javascript" src="vendor/flot/jquery.flot.js"></script>
<script type="text/javascript" src="vendor/flot/jquery.flot.time.js"></script>
<!-- Recline (only needed when NOT including the combined JS file as shown above) -->
<script type="text/javascript" src="src/view.graph.js"></script>
{% endhighlight %}
Next, create a new div for the graph:
{% highlight html %}
<div id="mygraph"></div>
{% endhighlight %}
Now let's create the graph, we will use the same dataset we had earlier, and we will need to set the view 'state' in order to configure the graph with the column to use for the x-axis ("group") and the columns to use for the series to show ("series").
<div class="alert alert-info">
<strong>State</strong>: The concept of a state is a common feature of Recline views being an object
which stores information about the state and configuration of a given view. You
can read more about it in the general <a href="../docs/views.html">Views
documentation</a> as well as the documentation of individual views such as the
<a href="../docs/src/view.graph.html">Graph View</a>.
</div>
{% highlight javascript %}
var $el = $('#mygraph');
var graph = new recline.View.Graph({
model: dataset,
state: {
graphType: "lines-and-points",
group: "date",
series: ["y", "z"]
}
});
$el.append(graph.el);
graph.render();
graph.redraw();
{% endhighlight %}
For the axis date formatting to work, it is crucial that the date type is set for that field as shown in the code concerning the dataset above. The result is the following graph:
<div id="mygraph" style="margin-bottom: 30px;">&nbsp;</div>
<script type="text/javascript">
dataset.fields.models[1].attributes.type = 'date';
var $el = $('#mygraph');
var graph = new recline.View.Graph({
model: dataset,
state: {
graphType: "lines-and-points",
group: "date",
series: ["y", "z"]
}
});
$el.append(graph.el);
graph.render();
graph.redraw();
</script>
### Creating a Map
<div class="alert alert-info">
The source code along with all dependencies for the map part of the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-map-demo">this GitHub repository</a>. See it in action via <a href="http://mattfullerton.github.io/recline-view-map-demo/">GitHub Pages</a>.
</div>
Now, let's create a map of this dataset using the lon/lat information which is
present on these data points.
First, add the additional dependencies for the map view. These are the Leaflet
library and the Recline Map view:
{% highlight html %}
<!-- css -->
<link rel="stylesheet" href="vendor/leaflet/0.7.3/leaflet.css">
<!--[if lte IE 8]>
<link rel="stylesheet" href="vendor/leaflet/0.7.3/leaflet.ie.css" />
<![endif]-->
<link rel="stylesheet" href="vendor/leaflet.markercluster/MarkerCluster.css">
<link rel="stylesheet" href="vendor/leaflet.markercluster/MarkerCluster.Default.css">
<link rel="stylesheet" href="css/map.css">
<!-- javascript -->
<script type="text/javascript" src="vendor/leaflet/0.7.3/leaflet.js"></script>
<script type="text/javascript" src="vendor/leaflet.markercluster/leaflet.markercluster.js"></script>
<!-- Recline (only needed when NOT including the combined JS file as shown above) -->
<script type="text/javascript" src="src/view-map.js"></script>
{% endhighlight %}
Now, create a new div for the map:
{% highlight html %}
<div id="mymap"></div>
{% endhighlight %}
Now let's create the map, we will use the existing dataset object created
previously:
{% highlight javascript %}
var $el = $('#mymap');
var map = new recline.View.Map({
model: dataset
});
$el.append(map.el);
map.render();
{% endhighlight %}
<div id="mymap">&nbsp;</div>
<script type="text/javascript">
var $el = $('#mymap');
var map = new recline.View.Map({
model: dataset
});
$el.append(map.el);
map.render();
</script>
### Creating a Timeline
<div class="alert alert-info">
The source code along with all dependencies for the timeline part of the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-timeline-demo">this GitHub repository</a>. See it in action via <a href="http://mattfullerton.github.io/recline-view-timeline-demo/">GitHub Pages</a>.
</div>
Now, let's create a timeline for this dataset using the date information which is
present on these data points.
First, add the additional dependencies for the timeline view. The timeline is built on the excellent Verite Timeline widget so that library is the key one for this view:
{% highlight html %}
<!-- css -->
<link rel="stylesheet" href="vendor/timeline/css/timeline.css">
<link rel="stylesheet" href="css/map.css">
<!-- javascript -->
<script type="text/javascript" src="vendor/moment/2.0.0/moment.js"></script>
<script type="text/javascript" src="vendor/timeline/js/timeline.js"></script>
{% endhighlight %}
Now, create a new div for the map (must have an explicit height for the timeline to render):
{% highlight html %}
<style type="text/css">#mytimeline .recline-timeline { height: 400px; }</style>
<div id="mytimeline"></div>
{% endhighlight %}
Now let's create the timeline, we will use the existing dataset object created
previously:
{% highlight javascript %}
{% include tutorial-views-timeline.js %}
{% endhighlight %}
<style type="text/css">#mytimeline .recline-timeline { height: 400px; }</style>
<div id="mytimeline"></div>
<div style="clear: both;"></div>
<script type="text/javascript">
{% include tutorial-views-timeline.js %}
</script>

View File

@@ -1,67 +0,0 @@
---
layout: container
title: Tutorials
root: ../
---
<div class="page-header">
<h1>
Tutorials
</h1>
</div>
<h3>Basics &ndash; Using the Dataset and its Friends</h3>
<hr />
<div id="tutorials" class="tutorials container">
<div class="row">
<div class="col-md-4">
<div class="well">
<h4><a href="tutorial-basics.html">Dataset Basics</a></h4>
</div>
</div>
<div class="col-md-4">
<div class="well">
<h4><a href="tutorial-basics-query.html">Dataset Querying</a></h4>
</div>
</div>
<div class="col-md-4">
<div class="well">
<h4><a href="tutorial-basics-events.html">Datasets and Events</a></h4>
</div>
</div>
</div>
</div>
<h3>Backends &ndash; Loading and Storing Data from Remote Sources</h3>
<hr />
<div class="tutorials container">
<div class="row">
<div class="col-md-4">
<div class="well">
<h4><a href="tutorial-backends.html">Backends: loading data from Google Docs, Local CSV, DataHub &amp; more ...</a></h4>
</div>
</div>
</div>
</div>
<h3>Views &ndash; visualize data</h3>
<hr />
<div class="tutorials container">
<div class="row">
<div class="col-md-4">
<div class="well">
<h4><a href="tutorial-views.html">Views Quickstart - Grids, Graphs, Maps &amp; Timelines</a></h4>
</div>
</div>
<div class="col-md-4">
<div class="well">
<h4><a href="tutorial-multiview.html">Multiview - Multiple tabbed views</a></h4>
</div>
</div>
<div class="col-md-4">
<div class="well">
<h4><a href="tutorial-maps.html">Doing more with maps</a></h4>
</div>
</div>
</div>
</div>

View File

@@ -1,198 +0,0 @@
---
layout: container
title: Library - Views
root: ../
---
<div class="page-header">
<h1>
Recline Views
</h1>
</div>
Recline Views are instances of Backbone Views and they act as 'WUI' (web user
interface) component displaying some model object in the DOM. Like all Backbone
views they have a pointer to a model (or a collection) and have an associated
DOM-style element (usually this element will be bound into the page at some
point).
<div class="alert alert-info">Looking for quickstart tutorial rather than reference documentation? See the <a href="tutorial-views.html">Views Tutorial</a>.</div>
Views provided by core Recline are crudely divided into two types:
* Dataset Views: a View intended for displaying a recline.Model.Dataset in some
fashion. Examples are the Grid, Graph and Map views.
* Widget Views: a widget used for displaying some specific (and smaller) aspect
of a dataset or the application. Examples are QueryEditor and FilterEditor
which both provide a way for editing (a part of) a `recline.Model.Query`
associated to a Dataset.
## Dataset Views currently available
{% include views-list.html %}
## Dataset View
These views are just Backbone views with a few additional conventions:
1. The model passed to the View should always be a recline.Model.Dataset
instance
2. Views should generate their own root element rather than having it passed
in.
3. Views should apply a css class named 'recline-{view-name-lower-cased} to the
root element (and for all CSS for this view to be qualified using this CSS
class)
4. Read-only mode: CSS for this view should respect/utilize a parent
recline-read-only class in order to trigger read-only behaviour (this class
will usually be set on some parent element of the view's root element).
5. State: state (configuration) information for the view should be stored on an
attribute named state that is an instance of a Backbone Model (or, more
speficially, be an instance of `recline.Model.ObjectState`). In addition, a
state attribute may be specified in the Hash passed to a View on
iniitialization and this information should be used to set the initial state
of the view.
Example of state would be the set of fields being plotted in a graph view.
More information about State can be found below.
To summarize some of this, the initialize function for a Dataset View should
look like:
<pre>
initialize: {
model: {a recline.Model.Dataset instance}
// el: {do not specify - instead view should create}
state: {(optional) Object / Hash specifying initial state}
...
}
</pre>
Note: Dataset Views in core Recline have a common layout on disk as follows,
where ViewName is the named of View class:
<pre>
src/view-{lower-case-ViewName}.js
css/{lower-case-ViewName}.css
test/view-{lower-case-ViewName}.js
</pre>
### State
State information exists in order to support state serialization into the url
or elsewhere and reloading of application from a stored state.
State is available not only for individual views (as described above) but for
the dataset (e.g. the current query). For an example of pulling together state
from across multiple components see `recline.View.DataExplorer`.
### Flash Messages / Notifications
To send 'flash messages' or notifications the convention is that views should
fire an event named `recline:flash` with a payload that is a flash object with
the following attributes (all optional):
* message: message to show.
* category: warning (default), success, error
* persist: if true alert is persistent, o/w hidden after 3s (default=false)
* loader: if true show a loading message
Objects or views wishing to bind to flash messages may then subscribe to these
events and take some action such as displaying them to the user. For an example
of such behaviour see the DataExplorer view.
### Writing your own Views
See the existing Views.
## Internationalization
### Adding translations to templates
Internationalization is implemented with help of [intl-messageformat](https://www.npmjs.com/package/intl-messageformat) library and supports [ICU Message syntax](http://userguide.icu-project.org/formatparse/messages).
Translation keys are using Mustache tags prefixed by `t.`. You can specify translated strings in two ways:
1. Simple text with no variables is rendered using Mustache variable-tag
```javascript
$template = '{{ "{{t.Add_row"}}}}'; // will show "Add row" in defaultLocale (English)
```
2. Text with variables or special characters is rendered using Mustache section-tag
```javascript
$template = '{{ "{{#t.desc"}}}}Add first_row field{{ "{{/t.desc"}}}}';
// using special chars; will show "Add first_row field" in defaultLocale
$template = '{{ "{{#t.num_records"}}}}{recordCount, plural, =0 {no records} =1{# record} other {# records}}{{ "{{/t.num_records"}}}}';
// will show "no records", "1 record" or "x records" in defaultLocale (English)
```
When using section-tags in existing templates be sure to remove a bracket from variables inside sections:
```javascript
#template___notranslation = '{{ "{{recordCount"}}}} records';
#template_withtranslation = '{{ "{{#t.num_records"}}}} {recordCount} records {{ "{{/t.num_records"}}}}';
```
Then setup Mustache to use translation by injecting tranlation tags in `render` function:
```javascript
// ============== BEFORE ===================
my.MultiView = Backbone.View.extend({
render: function() {
var tmplData = this.model.toTemplateJSON();
var output = Mustache.render(this.template, tmplData);
...
}
});
// ============== AFTER ====================
my.MultiView = Backbone.View.extend({
render: function() {
var tmplData = this.model.toTemplateJSON();
tmplData = I18nMessages('recline', recline.View.translations).injectMustache(tmplData); // inject Moustache formatter
var output = Mustache.render(this.template, tmplData);
...
}
});
```
### Language resolution
By default the language is detected from the root `lang` attributes - <html lang="xx">` and `<html xml:lang="xx">`.
If you want to override this functionality then override `I18nMessages.languageResolver` with your implementation.
```html
<script type="text/javascript" src="common-intl-wmustache.js"></script>
<script type="text/javascript">
I18nMessages.languageResolver = function() {
// implement here your language resolution
return 'fr';
};
</script>
```
Libraries can also ask for specific language: `I18nMessages('recline', recline.View.translations, 'pl')`. Language resolver is not used in that case.
If you're creating templates using default language other than English (why?) set appropriately appHardcodedLocale: `I18nMessages('recline', recline.View.translations, undefined, 'pl')`. Then missing strings won't be reported in console and underscores in simple translations will be converted to spaces.
### Adding new language
Create a copy of `src/i18n/pl.js` and translate all the keys. Long English messages can be found in `en.js`.
### Overriding defined messages
If you want to override translations from provided locale do it in a script tag after including recline:
```html
<script type="text/javascript" src="recline.js"></script>
<script type="text/javascript">
this.recline.View.translations['en'] = {
Add_row: 'Add new row'
}
</script>
```