[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

6
.gitignore vendored
View File

@ -1,6 +0,0 @@
.DS_Store
sandbox/*
.*.swp
.*.swo
_site/*
node_modules/*

View File

@ -1,4 +0,0 @@
language: node_js
node_js:
- "0.10"
script: phantomjs test/qunit/runner.js test/index.html

View File

@ -1,43 +0,0 @@
# Contributing to Recline
We welcome patches and pull requests. There are a few guidelines.
## General
* Please run the tests :-) (see below)
* Please do **not** build the dist files (e.g. dist/recline.js) when submitting
patches. dist files will get built automatically and if they are part of a
patch or pull request it makes them harder to review and more likely to
conflict.
* If possible have an issue to which the commits can relate. You can reference
an issue in the commits by just including #{issue-number} somewhere in the
commit message). Note if no issue exists suggest creating one.
## For larger changes
* Cleanup your code and affected code parts
* Run the tests from `/test/index.html` in different browsers (at least Chrome and FF)
* Update the documentation and tutorials where necessary
* Update `/_includes/recline-deps.html` if you change required files (e.g. leaflet libraries)
* Try to build the demos in `/demos/` with jekyll and then check out the `/demos/multiview/` which utilizes most aspects of Recline
You will also probably want to take a quick look at outline of the architecture which can be found in the [documentation online](http://okfnlabs.org/recline).
## Running tests
Run the tests by opening `test/index.html` in your browser.
## Demos and Documentation
Note that the demos and documentation utilize the [jekyll templating
system][jekyll] and to use them *locally* you will need to build them using
jekyll. Once installed, all you need to do from the command line is run jekyll:
jekyll serve
or if you're actively developing and want auto-reloading:
jekyll serve --watch
[jekyll]: https://github.com/mojombo/jekyll

View File

@ -1,20 +0,0 @@
Copyright (c) 2011-2014 Max Ogden, Rufus Pollock and Contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

148
README.md
View File

@ -1,148 +0,0 @@
[![Build Status](https://travis-ci.org/datopian/recline.png)](https://travis-ci.org/datopian/recline)
A simple but powerful library for building data applications in pure Javascript and HTML.
<h3><a href="http://datopian.github.io/recline/">Recline Website - including Overview, Documentation, Demos etc</a></h3>
## Features
* Open-source (and heavy reuser of existing open-source libraries)
* Pure javascript (no Flash) and designed for integration -- so it is easy to
embed in other sites and applications
* View and edit your data in clean grid interface
* Bulk update/clean your data using an easy scripting UI
* Visualize your data
* And more ... see <http://okfnlabs.org/recline/>
## Contributing
See CONTRIBUTING.md.
### Contributors
* [Rufus Pollock](http://rufuspollock.org/)
* [Max Ogden](http://maxogden.com/)
* [John Glover](https://github.com/johnglover)
* [James Casbon](http://casbon.me/)
* [Adrià Mercader](http://amercader.net/)
* [Dominik Moritz](https://github.com/domoritz)
* [Friedrich Lindenberg](http://pudo.org/)
* [Alioune Dia](https://github.com/aliounedia)
* [kielni](https://github.com/kielni)
* And [many more](https://github.com/okfn/recline/graphs/contributors)
## Changelog
### v0.7 - Summer 2014 (tbc)
[v0.7 milestone](https://github.com/okfn/recline/issues?milestone=7)
Possible breaking changes
* Support for row/add/delete/Reorder for recline slickGrid check `_includes/recline-deps.html` for slcikGrid plugins required #396
* Upgraded timelinejs lib - #316
* Removed csv backend (as now in separate repo) #444
### v0.6 - Summer 2013
[v0.6 milestone](https://github.com/okfn/recline/issues?milestone=5) (more than 40 issues)
Possible breaking changes
* Many backends moved to their own repositories #314
* Upgarde to Backbone v1.0 #351
* Updated Leaflet to latest version 0.4.4 #220
* Added marker clustering in map view to handle a large number of markers (and allowed it to disabled)
* Dataset.restore method removed (not used internally except from Multiview.restore)
* Views no longer call render in initialize but must be called client code
* Backend.Memory.Store attribute for holding 'records' renamed to `records` from `data`
* Option to use underscore.deferred vendor library and not use jQuery (jQuery no longer required if just using recline.dataset.js)
* View.el is now the raw DOM element. If you want a jQuery-wrapped version, use view.$el. #350
* Pager widget now takes Dataset object rather than QueryState object #386
### v0.5 - July 5th 2012 (first public release)
[40 closed issues](https://github.com/okfn/recline/issues?milestone=2&page=1&state=closed)
Lots of breaking changes to the API from v0.4 (should be very few going forwards) including:
* State only stores backend (name) and dataset url (in url field) rather than entire dataset object
* Backends heavily reorganized
* Rename Document -> Record
* Rename DataExplorer view to MultiView
* ...
### v0.4 - April 26th 2012
[23 closed issues](https://github.com/okfn/recline/issues?milestone=2&page=1&state=closed) including:
* Map view using Leaflet - #69, #64, #89, #97
* Term filter support - #66
* Faceting support- #62
* Tidy up CSS and JS - #81 and #78
* Manage and serialize view and dataset state (plus support for embed and permalinks) - #88, #67
* Graph view improvements e.g. handle date types correctly - #75
* Write support for ES backend - #61
* Remove JQuery-UI dependency in favour of bootstrap modal - #46
* Improved CSV import support - #92
### v0.3 - March 31st 2012
[16 closed issues](https://github.com/okfn/recline/issues?milestone=1&state=closed) including:
* ElasticSearch (and hence DataHub/CKAN) backend - #54
* Loading of local CSV files - #36
* Fully worked out Data Query support - #34, #49, #53, #57
* New Field model object for richer field information - #25
* Upgrade to Bootstrap v2.0 - #55
* Recline Data Explorer app improvements e.g. #39 (import menu)
* Graph improvements - #58 (more graph types, graph interaction)
### v0.2 - Feb 24th 2012
[17 closed issues](https://github.com/okfn/recline/issues?milestone=3&state=closed) including:
* Major refactor of backend and model relationship - #35 and #43
* Support Google Docs Spreadsheets as a Backend - #15
* Support for online CSV and Excel files via DataProxy backend - #31
* Data Explorer is customizable re loaded views - #42
* Start of documentation - #33
* Views in separate files - #41
* Better error reporting from backends on JSONP errors - #30
* Sorting and show/hide of columns in data grid - #23, #29
* Support for pagination - #27
* Split backends into separate files to make them easier to maintain and reuse separately #50
### v0.1 - Jan 28th 2012
* Core models and structure including Dataset and Document
* Memory and webstore backends
* Grid, Graph and Data Explorer views
* Bootstrap-based theme - #22
## Copyright and License
Copyright 2011 Max Ogden and Rufus Pollock.
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,6 +0,0 @@
highlighter: pygments
markdown: kramdown
title: Recline Data Explorer and Library
exclude: []

View File

@ -1,9 +0,0 @@
* <a href="https://github.com/okfn/recline.backend.gdocs">gdocs: Google Docs (Spreadsheet)</a>
* <a href="https://github.com/okfn/csv.js">csv: CSV files</a>
* <a href="https://github.com/NuCivic/recline.backend.xlsx">xlsx: Excel files</a>
* <a href="https://github.com/okfn/recline.backend.solr">solr: SOLR</a> (partial)
* <a href="https://github.com/okfn/elasticsearch.js">elasticsearch: ElasticSearch</a>
* <a href="{{page.root}}/docs/src/backend.dataproxy.html">dataproxy: DataProxy (CSV and XLS on the Web)</a>
* <a href="https://github.com/okfn/ckan.js">ckan: CKAN</a> &ndash; support for <a href="http://docs.ckan.org/en/latest/datastore.html">CKAN datastore</a>
* <a href="https://github.com/okfn/recline.backend.couchdb">couchdb: CouchDB</a>
* <a href="{{page.root}}/docs/src/backend.memory.html">memory: Memory (local data)</a>

View File

@ -1,9 +0,0 @@
var data = [
{id: 0, date: '2011-01-01', x: 1, y: 2, z: 3, country: 'DE', geo: {lat:52.56, lon:13.40} },
{id: 1, date: '2011-02-02', x: 2, y: 4, z: 24, country: 'UK', geo: {lat:54.97, lon:-1.60}},
{id: 2, date: '2011-03-03', x: 3, y: 6, z: 9, country: 'US', geo: {lat:40.00, lon:-75.5}},
{id: 3, date: '2011-04-04', x: 4, y: 8, z: 6, country: 'UK', geo: {lat:57.27, lon:-6.20}},
{id: 4, date: '2011-05-04', x: 5, y: 10, z: 15, country: 'UK', geo: {lat:51.58, lon:0}},
{id: 5, date: '2011-06-02', x: 6, y: 12, z: 18, country: 'DE', geo: {lat:51.04, lon:7.9}}
];

View File

@ -1,22 +0,0 @@
// the file input
var $file = $('.my-file-input')[0];
// listen for the file to be submitted
$($file).change(function(e) {
// create the dataset in the usual way but specifying file attribute
var dataset = new recline.Model.Dataset({
file: $file.files[0],
backend: 'csv'
});
// now load - note that this is again async (HTML5 File API is async)
// dataset.fetch().done(function() { console.log('here'); });
dataset.fetch();
// For demonstrations purposes display the data in a grid
var grid = new recline.View.Grid({
model: dataset
});
$('#my-csv-disk').append(grid.el);
});

View File

@ -1,17 +0,0 @@
var dataset = new recline.Model.Dataset({
url: 'http://data.london.gov.uk/datafiles/transport/tfl_passengers.csv',
// optional rows parameter specifies how many rows to retrieve - default is a 1000
// rows: 5000
backend: 'dataproxy'
});
// async again as we fetch via AJAX behind the scenes
// once data is fetched it will be stored in a local MemoryStore so further querying will not involve the DataProxy
dataset.fetch();
// For demonstrations purposes display the data in a grid
var grid = new recline.View.Grid({
model: dataset
});
$('#my-dataproxy').append(grid.el);

View File

@ -1,21 +0,0 @@
// Create a dataset with a Google Docs backend and a url to the Google Doc
var dataset = new recline.Model.Dataset({
url: 'https://docs.google.com/spreadsheet/ccc?key=0Aon3JiuouxLUdGZPaUZsMjBxeGhfOWRlWm85MmV0UUE#gid=0',
backend: 'gdocs'
});
// Optional - display the results in a grid
// Note how we can set this up before any data has arrived
// Views will listen for query completion and update themselves automatically
var grid = new recline.View.Grid({
model: dataset
});
$('#my-gdocs').append(grid.el);
// Now do the query to the backend to load data
dataset.fetch().done(function(dataset) {
if (console) {
console.log(dataset.records);
}
});

View File

@ -1,21 +0,0 @@
// Create the dataset in the usual way
// Note the additional options you can specify for parsing the CSV file
var dataset = new recline.Model.Dataset({
url: '{{page.root}}demos/data/sample.csv',
backend: 'csv',
// delimiter: ',',
// quotechar: '"',
// encoding: 'utf8'
});
// remember this is async so if you want to do something you need to call it in done method e.g.
// dataset.fetch.done(function(dataset) { console.log(dataset.recordCount)});
dataset.fetch();
// show the data for illustrations sake
var grid = new recline.View.SlickGrid({
model: dataset,
el: $('#my-online-csv')
});
grid.visible = true;

View File

@ -1,88 +0,0 @@
<link rel="stylesheet" href="{{page.root}}vendor/leaflet/0.7.3/leaflet.css">
<!--[if lte IE 8]>
<link rel="stylesheet" href="{{page.root}}vendor/leaflet/0.7.3/leaflet.ie.css" />
<![endif]-->
<link rel="stylesheet" href="{{page.root}}vendor/leaflet.markercluster/MarkerCluster.css">
<link rel="stylesheet" href="{{page.root}}vendor/leaflet.markercluster/MarkerCluster.Default.css">
<link rel="stylesheet" href="{{page.root}}vendor/slickgrid/2.2/slick.grid.css">
<link rel="stylesheet" href="{{page.root}}vendor/timeline/css/timeline.css">
<!-- Recline CSS components -->
<link rel="stylesheet" href="{{page.root}}css/grid.css">
<link rel="stylesheet" href="{{page.root}}css/slickgrid.css">
<link rel="stylesheet" href="{{page.root}}css/flot.css">
<link rel="stylesheet" href="{{page.root}}css/map.css">
<link rel="stylesheet" href="{{page.root}}css/multiview.css">
<link rel="stylesheet" href="{{page.root}}css/timeline.css">
<!-- /Recline CSS components -->
<!-- 3rd party JS libraries -->
<!--script type="text/javascript" src="{{page.root}}vendor/jquery/1.7.1/jquery.js"></script-->
<script src="{{page.root}}vendor/slickgrid/2.2/jquery-1.7.min.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/underscore/1.4.4/underscore.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/backbone/1.0.0/backbone.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/mustache/0.5.0-dev/mustache.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/bootstrap/3.2.0/js/bootstrap.js"></script>
<!--[if lte IE 8]>
<script language="javascript" type="text/javascript" src="{{page.root}}vendor/flot/excanvas.min.js"></script>
<![endif]-->
<script type="text/javascript" src="{{page.root}}vendor/flot/jquery.flot.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/flot/jquery.flot.time.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/leaflet/0.7.3/leaflet.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/leaflet.markercluster/leaflet.markercluster.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.2/jquery-ui-1.8.16.custom.min.js"></script>
<script src="{{page.root}}vendor/slickgrid/2.2/jquery.event.drag-2.2.js"></script>
<script src="{{page.root}}vendor/slickgrid/2.2/jquery.event.drop-2.2.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.2/jquery.event.drag-2.2.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.2/slick.core.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.2/slick.formatters.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.2/slick.editors.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.2/slick.grid.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.2/plugins/slick.rowselectionmodel.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.2/plugins/slick.rowmovemanager.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/moment/2.0.0/moment.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/timeline/js/timeline.js"></script>
<script type="text/javascript" src="{{page.root}}node_modules/intl-messageformat/dist/intl-messageformat-with-locales.min.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/common-intl-wmustache.js"></script>
<!--[if lte IE 7]>
<script language="javascript" type="text/javascript" src="{{page.root}}vendor/json/json2.js"></script>
<![endif]-->
<!--
## Just use the all in one library version rather than individual files
<script type="text/javascript" src="{{page.root}}dist/recline.js"></script>
-->
<!-- model and backends -->
<script type="text/javascript" src="{{page.root}}src/ecma-fixes.js"></script>
<script type="text/javascript" src="{{page.root}}src/model.js"></script>
<script type="text/javascript" src="{{page.root}}src/backend.memory.js"></script>
<script type="text/javascript" src="{{page.root}}src/backend.dataproxy.js"></script>
<script type="text/javascript" src="http://okfnlabs.org/recline.backend.gdocs/backend.gdocs.js"></script>
<script type="text/javascript" src="http://okfnlabs.org/csv.js/csv.js"></script>
<!-- views -->
<script type="text/javascript" src="{{page.root}}src/i18n/en.js"></script>
<script type="text/javascript" src="{{page.root}}src/i18n/pl.js"></script>
<script type="text/javascript" src="{{page.root}}src/view.grid.js"></script>
<script type="text/javascript" src="{{page.root}}src/view.slickgrid.js"></script>
<script type="text/javascript" src="{{page.root}}src/view.flot.js"></script>
<script type="text/javascript" src="{{page.root}}src/view.graph.js"></script>
<script type="text/javascript" src="{{page.root}}src/view.map.js"></script>
<script type="text/javascript" src="{{page.root}}src/view.timeline.js"></script>
<script type="text/javascript" src="{{page.root}}src/widget.pager.js"></script>
<script type="text/javascript" src="{{page.root}}src/widget.queryeditor.js"></script>
<script type="text/javascript" src="{{page.root}}src/widget.filtereditor.js"></script>
<script type="text/javascript" src="{{page.root}}src/widget.valuefilter.js"></script>
<script type="text/javascript" src="{{page.root}}src/widget.facetviewer.js"></script>
<script type="text/javascript" src="{{page.root}}src/widget.fields.js"></script>
<script type="text/javascript" src="{{page.root}}src/view.multiview.js"></script>

View File

@ -1,29 +0,0 @@
// (for convenience) assume availability of jquery
// must have div with class="ex-1"
var $el = $('.ex-1');
// total number of records resulting from latest query
$el.append('Total found: ' + dataset.recordCount + '<br />');
$el.append('Total returned: ' + dataset.records.length);
$el.append('<hr />');
// get 2nd record in list (note collection indexes off 0!)
// this is an instance of a Record object
var record = dataset.records.at(1);
// if records have an id you can get by id too ...
// var record = dataset.records.get(record-id);
// To get record attribute we use 'get'
var recdate = record.get('date');
$el.append('Date is: ' + recdate);
$el.append('<hr />');
// We can also convert the Record back to simple JS object
var simple = record.toJSON();
$el.append('<h4>Record as simple object</h4>');
$el.append('<pre>' + JSON.stringify(simple, null, 2) + '</pre>');

View File

@ -1,19 +0,0 @@
// must have a div with class="ex-1"
var $el = $('.ex-2');
// query with text 'UK' - this will attempt to match any field for UK
// Also limit the query to return a maximum of 2 results using the size attribute
// query function has asynchronous behaviour and returns a promise object
// (even for the case of in memory data where querying in fact happens synchronously)
// On completion the display function will be called
dataset.query({q: 'UK', size: 2}).done(function() {
$('.ex-2').append('Total found: ' + dataset.recordCount);
$('.ex-2').append(' Total returned: ' + dataset.records.length);
$('.ex-2').append(
$('<pre />').html(
JSON.stringify(dataset.records.toJSON(), null, 2)
)
);
});

View File

@ -1,13 +0,0 @@
function onChange() {
$('.ex-events').append('Queried: ' + dataset.queryState.get('q') + '. Records matching: ' + dataset.recordCount);
$('.ex-events').append('<br />');
}
dataset.records.bind('reset', onChange);
dataset.query({q: 'DE'});
dataset.query({q: 'UK'});
dataset.query({q: 'US'});
dataset.unbind('reset', onChange);

View File

@ -1,10 +0,0 @@
var $el = $('.ex-fields-2');
dataset.fields.models[6] = new recline.Model.Field({
id: 'geo',
label: 'Location',
type: 'geo_point'
});
var rec = dataset.records.at(0);
$el.append(record.summary());

View File

@ -1,20 +0,0 @@
var $el = $('.ex-fields');
// Now list the Fields of this Dataset (these will have be automatically extracted from the data)
$el.append('Fields: ');
// Dataset.fields is a Backbone collection of Fields (i.e. record attributes)
dataset.fields.each(function(field) {
$el.append(field.id + ' || ');
});
$el.append('<hr />');
// Show all field info
var json = dataset.fields.toJSON();
$el.append(
$('<pre />')
.append(
JSON.stringify(json, null, 2)
)
);

View File

@ -1,17 +0,0 @@
var $el = $('#map-customize');
var view = new recline.View.Map({
el: $el,
model: dataset
});
view.geoJsonLayerOptions.pointToLayer = function(feature, latlng) {
// Look up Record so we can use it to customize size of marker
// note that 'this' is specially bound for us to parent view + that feature
// stores record cid
var record = this.model.records.getByCid(feature.properties.cid);
var marker = new L.CircleMarker(latlng, { radius: record.get('x') * 3 });
marker.bindPopup(feature.properties.popupContent);
return marker;
}
view.render();

View File

@ -1,14 +0,0 @@
// this element will need to exist!
var $el = $('#map-infobox');
var view = new recline.View.Map({
el: $el,
model: dataset
});
// record is the recline.Model.Record object
view.infobox = function(record) {
var html = '<h3>' + record.get('country') + ' &ndash; ' + record.get('date') + '</h3>';
html += 'id: ' + record.get('id');
return html;
}
view.render();

View File

@ -1,15 +0,0 @@
var $el = $('#mytimeline');
var timeline = new recline.View.Timeline({
model: dataset
});
$el.append(timeline.el);
// set the headline/title for each record with x column
timeline.convertRecord = function(record, fields) {
var out = this._convertRecord(record);
if (out) {
out.headline = record.get('x').toString();
}
return out;
}
timeline.render();

View File

@ -1,7 +0,0 @@
* <a href="{{page.root}}docs/src/view.grid.html">Grid (simple)</a>
* <a href="{{page.root}}docs/src/view.slickgrid.html">Grid (SlickGrid)</a>
* <a href="{{page.root}}docs/src/view.map.html">Map</a>
* <a href="https://github.com/NuCivic/recline.view.choroplethmap.js">Choropleth Map</a>
* <a href="{{page.root}}docs/src/view.graph.html">Graph</a>
* <a href="{{page.root}}docs/src/view.timeline.html">Timeline</a>
* <a href="{{page.root}}docs/src/view.multiview.html">Multiview (combines views)</a>

View File

@ -1,8 +0,0 @@
---
layout: default
---
<div class="container">
{{content}}
</div>

View File

@ -1,128 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>{{ page.title }} - Recline Data Explorer and Library</title>
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="{{ page.root }}vendor/bootstrap/3.2.0/css/bootstrap.css" />
{% if page.recline-deps %}
{% include recline-deps.html %}
{% endif %}
<!-- link rel="stylesheet" href="vendor/bootstrap/3.2.0/css/bootstrap-responsive.css" -->
<link href="{{ page.root }}css-site/pygments.css" rel="stylesheet" type="text/css" />
<link href="{{ page.root }}css-site/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{page.root}}">
<img class="logo-icon" src="http://assets.okfn.org/p/recline/img/chair.png" />
<strong>Recline.js</strong> &ndash; relax with your data
</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li>
<a href="{{page.root}}docs/">
<i class="glyphicon glyphicon-book icon-white"></i>
Documentation
</a>
</li>
<li class="divider-vertical"></li>
<li>
<a href="{{page.root}}docs/tutorials.html">
<i class="glyphicon glyphicon-road icon-white"></i>
Tutorials
</a>
</li>
<li class="divider-vertical"></li>
<li>
<a href="{{page.root}}demos/">
<i class="glyphicon glyphicon-pencil icon-white"></i>
Demos
</a>
</li>
<li class="divider-vertical"></li>
<li>
<a href="{{page.root}}download.html">
<i class="glyphicon glyphicon-download-alt icon-white"></i>
Download
</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="http://github.com/okfn/recline/" title="Recline on Github">
<iframe src="http://ghbtns.com/github-btn.html?user=okfn&repo=recline&type=watch&count=true"
allowtransparency="true" frameborder="0" scrolling="0" width="90" height="20"></iframe>
</a>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
{{content}}
<section class="recline-footer">
<div class="container">
<div class="row">
<div class="col-md-3">
<p class="getit-btn"><a href="{{page.root}}docs/" class="btn btn-default">Use the Library &raquo;</a></p>
<p>Recline.js is freely redistributable under the terms of the MIT license.</p>
</div>
<div class="col-md-2">
<p><a href="http://www.shuttleworthfoundation.org/"><img src="http://farm8.staticflickr.com/7019/6467412887_18f72f5066_n.jpg" style="width: 140px;" alt="Supported by funding from the Shuttleworth Foundation" /></a></p>
<ul>
<li><a href="http://datahub.io/">The DataHub</a></li>
<li><a href="http://OpenSpending.org/">OpenSpending.org</a></li>
<li><a href="http://datacouch.com/">DataCouch.com</a></li>
</ul>
</div>
<div class="col-md-4">
<ul>
<li><a href="http://okfnlabs.org/">Open Knowledge Labs</a></li>
<li><a href="http://opendefinition.org/">Open Definition</a></li>
<li><a href="http://okfn.org/">Open Knowledge International</a></li>
</ul>
</div>
<div class="col-md-3">
<h4>Contacts</h4>
<ul style="list-style-type: none; margin-left: 0; padding: 0px;">
<li><a href="http://twitter.com/okfnlabs">@OKFNLabs</a></li>
<li><a href="http://twitter.com/maxogden">@maxogden</a></li>
<li><a href="http://twitter.com/rufuspollock">@rufuspollock</a></li>
</ul>
</div>
</div>
</section>
</div><!-- /.container -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-8271754-44']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,61 +0,0 @@
.hll { background-color: #ffffcc }
.c { color: #408080; font-style: italic } /* Comment */
.err { border: 1px solid #FF0000 } /* Error */
.k { color: #008000; font-weight: bold } /* Keyword */
.o { color: #666666 } /* Operator */
.cm { color: #408080; font-style: italic } /* Comment.Multiline */
.cp { color: #BC7A00 } /* Comment.Preproc */
.c1 { color: #408080; font-style: italic } /* Comment.Single */
.cs { color: #408080; font-style: italic } /* Comment.Special */
.gd { color: #A00000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #FF0000 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #00A000 } /* Generic.Inserted */
.go { color: #808080 } /* Generic.Output */
.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt { color: #0040D0 } /* Generic.Traceback */
.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.kp { color: #008000 } /* Keyword.Pseudo */
.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.kt { color: #B00040 } /* Keyword.Type */
.m { color: #666666 } /* Literal.Number */
.s { color: #BA2121 } /* Literal.String */
.na { color: #7D9029 } /* Name.Attribute */
.nb { color: #008000 } /* Name.Builtin */
.nc { color: #0000FF; font-weight: bold } /* Name.Class */
.no { color: #880000 } /* Name.Constant */
.nd { color: #AA22FF } /* Name.Decorator */
.ni { color: #999999; font-weight: bold } /* Name.Entity */
.ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.nf { color: #0000FF } /* Name.Function */
.nl { color: #A0A000 } /* Name.Label */
.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.nt { color: #008000; font-weight: bold } /* Name.Tag */
.nv { color: #19177C } /* Name.Variable */
.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #666666 } /* Literal.Number.Float */
.mh { color: #666666 } /* Literal.Number.Hex */
.mi { color: #666666 } /* Literal.Number.Integer */
.mo { color: #666666 } /* Literal.Number.Oct */
.sb { color: #BA2121 } /* Literal.String.Backtick */
.sc { color: #BA2121 } /* Literal.String.Char */
.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.s2 { color: #BA2121 } /* Literal.String.Double */
.se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.sh { color: #BA2121 } /* Literal.String.Heredoc */
.si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.sx { color: #008000 } /* Literal.String.Other */
.sr { color: #BB6688 } /* Literal.String.Regex */
.s1 { color: #BA2121 } /* Literal.String.Single */
.ss { color: #19177C } /* Literal.String.Symbol */
.bp { color: #008000 } /* Name.Builtin.Pseudo */
.vc { color: #19177C } /* Name.Variable.Class */
.vg { color: #19177C } /* Name.Variable.Global */
.vi { color: #19177C } /* Name.Variable.Instance */
.il { color: #666666 } /* Literal.Number.Integer.Long */

View File

@ -1,251 +0,0 @@
/*
Theme Name: Recline
Description: Layout and styling for reclinejs.com
Author: Sam Smith
Author URI: http://www.mintcanary.com/
*/
/* --------------------------------------------------
Table of Contents
-----------------------------------------------------
:: General Styles
:: Layout
::
::
::
*/
/* ---------------------------------------------------
General Styles
--------------------------------------------------- */
@import url(http://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700);
body, p {
font-family: 'PT Sans',Helvetica,Arial,sans-serif;
font-size: 15px;
}
h1, h2, h3, h4, h5, h6 {
font-family:'PT Sans',Helvetica, Arial, sans-serif;
font-weight: bold;
}
h2 {
font-size: 24px;
}
h3 {
font-size: 20px;
}
h4 {
font-size: 18px;
}
a {
color: #c7231d;
}
a:hover {
color: #bc130e;
}
/* ---------------------------------------------------
Layout
--------------------------------------------------- */
.navbar-header{
}
.navbar-header .logo-icon {
height: 34px;
}
.navbar-brand {
font-family:'PT Sans', Helvetica, Arial, sans-serif;
font-style:italic;
font-size:18px;
font-weight:400;
letter-spacing:-1px;
text-shadow: none !important;
color: #FFF !important;
margin-top: -6px;
}
.navbar-nav > li > a {
padding: 15px 10px;
font-size: 13px;
text-shadow: none !important;
color: #999 !important;
}
.navbar-nav > li > a:focus,
.navbar-nav > li > a:hover {
color: #FFF !important;
}
.navbar .divider-vertical {
height: 50px;
margin: 0 9px;
border-right: 1px solid #ffffff;
}
.navbar-inverse .divider-vertical {
border-right-color: #222222;
}
@media (max-width: 767px) {
.navbar-collapse .nav > .divider-vertical {
display: none;
}
}
.navbar {
height:50px;
background: #303030; /* Old browsers */
background: -moz-linear-gradient(top, #303030 0%, #2d2d2d 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#303030), color-stop(100%,#2d2d2d)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* IE10+ */
background: linear-gradient(top, #303030 0%,#2d2d2d 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#303030', endColorstr='#2d2d2d',GradientType=0 ); /* IE6-9 */
-webkit-box-shadow:none;
-moz-box-shadow: none;
box-shadow: none;
}
.icon-white{
color: #FFF;
margin-right: 1px;
}
a.btn,
button.btn {
white-space: normal !important;
}
body {
padding-top: 60px;
}
section {
padding-top:20px;
}
.home-page.page-header {
margin-top:-10px;
background: #2d2d2d; /* Old browsers */
background: -moz-linear-gradient(top, #2d2d2d 0%, #040404 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#2d2d2d), color-stop(100%,#040404)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #2d2d2d 0%,#040404 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #2d2d2d 0%,#040404 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #2d2d2d 0%,#040404 100%); /* IE10+ */
background: linear-gradient(top, #2d2d2d 0%,#040404 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#2d2d2d', endColorstr='#040404',GradientType=0 ); /* IE6-9 */
padding:0px;
margin-bottom:0px;
border:none;
padding: 60px;
padding-bottom: 200px;
/* hide crocodile top to footer on front page */
margin-bottom: -30px;
}
.home-page.page-header p {
color:#FFF;
}
.home-page.page-header a {
}
.home-page.page-header .container {
background-image: url(images/header-screen.png);
background-repeat: no-repeat;
background-position: -3px 0px;
}
.home-page.page-header .inner {
padding:0px 0px 0px 40px;
font-size:16px;
line-height: 23px;
width: 400px;
}
.home-page.page-header:after {
margin-top:-14px;
}
.home-page.page-header .links {
margin-top: 30px;
margin-bottom: 0;
}
.home-page.page-header .links a {
margin-left: 25px;
}
.home-page.page-header .links a:first-child {
margin-left: 0px;
}
/* ---------------------------------------------------
Footer
--------------------------------------------------- */
.recline-footer {
background-color:#040404;
color:#CCC;
margin-top: 30px;
}
.recline-footer:before {
content: " ";
height:14px;
display:block;
background-image: url(images/zigzags.png);
background-repeat: repeat-x;
background-position: center -100px;
margin-top:-34px;
}
.recline-footer:after {
display:none;
}
.recline-footer .row {
margin-top:15px;
margin-bottom:15px;
}
.recline-footer a {
color:#CCC;
}
.recline-footer a.btn {
color: #333333;
}
.tutorials .well {
height: 60px;
}
.tutorials:last-child {
margin-bottom: 200px;
}
/** Code / Pre **/
.container pre {
padding: 10px 15px;
border: 1px solid #ccc;
background: white;
color: #444;
box-shadow: 0 0 15px #ddd;
-moz-box-shadow: 0 0 15px #ddd;
-webkit-box-shadow: 0 0 15px #ddd;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.doc-ex-rendered {
margin-bottom: 20px;
}
#my-online-csv {
height: 100px;
}

View File

@ -1,26 +0,0 @@
.recline-flot .graph {
height: 500px;
overflow: hidden;
}
.recline-flot .legend table {
width: auto;
margin-bottom: 0;
}
.recline-flot .legend td {
padding: 5px;
line-height: 13px;
}
.recline-flot .graph .alert {
width: 450px;
}
#recline-flot-tooltip {
position: absolute;
background-color: #FEE;
color: #000000;
opacity: 0.8;
border: 1px solid #fdd;
}

View File

@ -1,221 +0,0 @@
/**********************************************************
* (Data) Grid
*********************************************************/
table.recline-grid {
table-layout: fixed;
width: 100%;
}
.recline-grid .btn-group .dropdown-toggle {
padding: 1px 3px;
line-height: auto;
}
.recline-grid td, .recline-grid th {
border-left: 1px solid #ccc;
padding: 3px 4px;
text-align: left;
word-wrap: break-word;
white-space: normal;
}
.recline-grid tbody tr {
vertical-align: top;
border-bottom: solid 1px #ccc;
}
.recline-grid tbody tr:last-child {
border-bottom: 1px solid #ccc;
}
.recline-grid tbody td:last-child {
border-right: 1px solid #ccc;
}
/* direct borrowing from twitter buttons */
.recline-grid th {
background-color: #e6e6e6;
background-repeat: no-repeat;
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6));
background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6);
background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
color: #333;
border: 1px solid #ccc;
border-bottom-color: #bbb;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-webkit-transition: 0.1s linear all;
-moz-transition: 0.1s linear all;
-ms-transition: 0.1s linear all;
-o-transition: 0.1s linear all;
transition: 0.1s linear all;
}
/**********************************************************
* Fixed Header - http://www.imaputz.com/cssStuff/bigFourVersion.html
*********************************************************/
div.table-container {
overflow: auto;
}
/* Reset overflow value to hidden for all non-IE browsers. */
html>body div.table-container {
overflow: hidden;
}
thead.fixed-header tr {
overflow-x: hidden;
}
/* set table header to a fixed position. WinIE 6.x only */
/* In WinIE 6.x, any element with a position property set to relative and is a child of */
/* an element that has an overflow property set, the relative value translates into fixed. */
/* Ex: parent element DIV with a class of table-container has an overflow property set to auto */
thead.fixed-header tr {
position: relative
}
/* set THEAD element to have block level attributes. All other non-IE browsers */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
html>body thead.fixed-header tr {
display: block
}
/* define the table content to be scrollable */
/* set TBODY element to have block level attributes. All other non-IE browsers */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
/* induced side effect is that child TDs no longer accept width: auto */
tbody.scroll-content {
display: block;
max-height: 500px;
overflow: auto;
}
/**********************************************************
* Data Table Menus
*********************************************************/
.column-header-menu, a.root-header-menu {
float: right;
}
div.data-table-cell-content {
line-height: 1.2;
color: #222;
position: relative;
}
div.data-table-cell-content-numeric {
text-align: right;
}
a.data-table-cell-edit {
position: absolute;
top: 0;
right: 0;
display: block;
width: 25px;
height: 16px;
text-decoration: none;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAQCAYAAABUWyyMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTNEODNFMjVEMDA5MTFERjk5NzhEQzZDRDUwRkEzMUEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTNEODNFMjZEMDA5MTFERjk5NzhEQzZDRDUwRkEzMUEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5M0Q4M0UyM0QwMDkxMURGOTk3OERDNkNENTBGQTMxQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5M0Q4M0UyNEQwMDkxMURGOTk3OERDNkNENTBGQTMxQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpApVmcAAAKVSURBVHjaYvz//z/DcAAsIGLaxjf2QKoLiM2oaPYpIC7L8hc5COI4F9+hmR17e1UOskAFVgCxBJUDyQxqriQ97GCCCpBkATCUGQxVOTHY7KyMDFoKHMhKJXCwCQJgKDNEOAlisHk5mRh8LPgw7GChNEg2HfvI8OnbPzDbwYAH6BkmhmsPflA12EtnPmN4/vY3mF0YKgb2zJYTn5CV/EfxiKgAC4O7CS8DHzczw5PXvxl2nv7E8PP3fxTx87e/o1hipMrFcOfZT6BmVgYZUTawmKUWN8Pxa1+xOkpNhp2hLk6CQVKYleHcrW8MTYteMHz+/g9FfMW+9yh6Ih0FGA5e/MLAAIx5IzUusFiqtzDD7K1vYUpcmZA1+FnxM7z++AccyqBkAgphmMPY2ZiAHvsMFkcGMkAPgMQ+ff3L8PPXPzD++O0vztDtypBmuPXkJziUebiYwSEMcxiID/IYiEYJLKDjQWLP3v1h+AI0G4RhMQQF5UzoDvr5CxIDoJhQlmKHy527/Y3hLjDkD4BCBgsAxSAoiYEwrqQFchAoWcBiAOQge30euBwoJkAh37/6FVb9oBgEeQCE0ZKWC8488vj1LzCmJTgLTKZn0ZIquYAJOURBsQDKB68//GHgYEWkOlBMgPICKIYcoCGIC4BiFRSDuEIUFBtSQizg5AWKHRgAxQSoZALFECy54QKgZAbLKxgegZVAfFxM4LyiLMUGTPeQ0ujAhS9gz7mb8sI9iisWQclSG7UIRgFlM56CM3R3uhTY0bC0DkpOtx//AGd4mEdxxSIoWaIVwQyMoCYKsGanWTsFWM8wQmt2mtkBqmdgMfKCRna8wMGmth2MMI/EAfEdKltwB2ouAz3sYBwurV8mhmECAAIMAEe3EkMWh/DvAAAAAElFTkSuQmCC);
background-repeat: no-repeat;
visibility: hidden;
}
a.data-table-cell-edit:hover {
background-position: -25px 0px;
}
.recline-grid td:hover .data-table-cell-edit {
visibility: visible;
}
div.data-table-cell-content-numeric > a.data-table-cell-edit {
left: 0px;
right: auto;
}
.data-table-value-nonstring {
color: #282;
}
.data-table-error {
color: red;
}
.data-table-cell-editor-editor {
overflow: hidden;
display: block;
width: 98%;
height: 3em;
font-family: monospace;
margin: 3px 0;
}
.data-table-cell-copypaste-editor {
overflow: hidden;
display: block;
width: 98%;
height: 10em;
font-family: monospace;
margin: 3px 0;
}
.data-table-cell-editor-action {
float: left;
vertical-align: bottom;
text-align: center;
}
.data-table-cell-editor-key {
font-size: 0.8em;
color: #999;
}
/**********************************************************
* Read-only mode
*********************************************************/
.recline-read-only .recline-grid .write-op,
.recline-read-only .recline-grid a.data-table-cell-edit
{
display: none;
}
.recline-read-only a.row-header-menu {
display: none;
}
/*************************
* WCAG 2.0
*************************/
.wcag_hide {
position:absolute;
top:0;
left:-10000px;
width:1px;
height:1px;
}
.wcag_hide2 {
clip: rect(1px, 1px, 1px, 1px);
display: block;
position: absolute;
}
.wcag_show_on_focus {
font-size: 0 !important;
}
.wcag_show_on_focus:focus {
font-size: 1em !important;
}

View File

@ -1,28 +0,0 @@
.recline-map .map {
height: 500px;
}
/**********************************************************
* Editor
*********************************************************/
.recline-map .editor {
float: right;
width: 200px;
padding-left: 0px;
margin-left: 10px;
}
.recline-map .editor form {
padding-left: 4px;
}
.recline-map .editor select {
width: 100%;
}
.recline-map .editor .editor-options {
margin-top: 10px;
border-top: 1px solid gray;
padding: 5px 0;
}

View File

@ -1,330 +0,0 @@
.recline-data-explorer .data-view-container {
display: block;
}
.recline-data-explorer .data-view-sidebar {
float: right;
margin-left: 8px;
width: 220px;
}
.recline-data-explorer .header .navigation {
margin-bottom: 8px;
}
.recline-data-explorer .header .navigation,
.recline-data-explorer .header .pagination,
.recline-data-explorer .header .pagination form
{
display: inline;
}
.recline-data-explorer .header .navigation {
float: left;
}
.recline-data-explorer .header .menu-right {
float: right;
margin-left: 5px;
padding-left: 5px;
}
.recline-results-info {
line-height: 35px;
margin-left: 20px;
float: left;
}
.recline-data-explorer .data-view-sidebar > div {
margin-top: 5px;
margin-bottom: 10px;
}
.recline-data-explorer .radio,
.recline-data-explorer .checkbox {
padding-left: 20px;
}
.recline-data-explorer .editor-update-map {
margin: 30px 0px 20px 0px;
}
.recline-data-explorer label {
font-weight: normal;
}
/**********************************************************
* Query Editor
*********************************************************/
.recline-query-editor {
float: right;
height: 35px;
padding-right: 5px;
margin-right: 5px;
border-right: solid 2px #ddd;
}
.header .input-prepend {
margin-bottom: auto;
}
.header .add-on {
float: left;
}
/* needed for Chrome but not FF */
.header .add-on {
margin-left: -27px;
}
/* needed for FF but not chrome */
.header .input-prepend {
vertical-align: top;
}
.recline-query-editor form button {
vertical-align: top;
}
/* label for screen reader */
.recline-query-editor .form-inline label {
position: absolute;
top:0;
left:-9999px
}
/**********************************************************
* Pager
*********************************************************/
.recline-pager {
float: left;
margin: auto;
display: block;
margin-left: 20px;
}
.recline-pager .pagination li {
display: inline-block;
}
.recline-pager .pagination label {
display:none;
}
.recline-pager .pagination input {
width: 40px;
height: 25px;
padding: 2px 4px;
margin: 0;
margin-top: -2px;
border: 1px solid #cccccc;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
transition: border linear 0.2s, box-shadow linear 0.2s;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
-webkit-border-radius: 4px;
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
-moz-border-radius: 4px;
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
}
.recline-pager .pagination a {
float: none;
margin-left: -5px;
color: #555;
}
.recline-pager .pagination .page-range {
height: 34px;
padding: 5px 8px;
margin-left: -5px;
border: 1px solid #ddd;
}
.recline-pager .pagination .page-range a {
padding: 0px 12px;
border: none;
}
.recline-pager .pagination .page-range a:hover {
background-color: #ffffff;
}
.recline-pager .pagination > li:first-child > a {
border-bottom-left-radius: 4px;
border-top-left-radius: 4px;
border-bottom-right-radius: 0px;
border-top-right-radius: 0px;
height: 34px;
}
.recline-pager .pagination > li:last-child > a {
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
border-bottom-left-radius: 0px;
border-top-left-radius: 0px;
height: 34px;
}
/**********************************************************
* Filter Editor
*********************************************************/
.recline-filter-editor {
padding: 8px;
display: none;
}
.recline-filter-editor .filters {
margin: 20px 0px;
}
.recline-filter-editor h3 {
margin-top: 4px;
}
.recline-filter-editor .filter {
margin-top: 20px;
}
.recline-filter-editor .filter .form-group {
margin-bottom: 0px;
}
.recline-filter-editor .filter input,
.recline-filter-editor .filter label {
margin: 0px;
}
.recline-filter-editor .js-edit button {
margin: 25px 0px 0px 0px;
}
.recline-filter-editor .filter-term a {
font-size: 18px;
}
.recline-filter-editor input,
.recline-filter-editor select
{
width: 175px;
}
.recline-filter-editor input {
margin-top: 0.5em;
margin-bottom: 10px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 1px solid #cccccc;
}
.recline-filter-editor label {
font-weight: normal;
display: block;
}
.recline-filter-editor legend {
margin-bottom: 5px;
}
.recline-filter-editor .add-filter {
margin-top: 1em;
margin-bottom: 2em;
}
.recline-filter-editor .update-filter {
margin-top: 1em;
}
/**********************************************************
* Fields Widget
*********************************************************/
.recline-fields-view {
display: none;
}
.recline-fields-view .fields-list {
padding: 0;
}
.recline-fields-view .panel {
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
}
.recline-fields-view .panel-group h3 {
padding-left: 10px;
}
.recline-fields-view .fields-list .panel-heading {
padding: 2px 5px;
margin: 1px 0px 1px 5px;
}
.recline-fields-view .panel a,
.recline-fields-view .panel h4 {
display: inline;
}
.recline-fields-view .panel a {
padding: 0;
}
.recline-fields-view .panel h4 {
word-wrap: break-word
}
.recline-fields-view .clear {
clear: both;
}
.recline-fields-view .facet-items {
list-style-type: none;
margin-left: 0;
}
.recline-fields-view .facet-item .term {
font-weight: bold;
}
.recline-fields-view .facet-item .count {
}
/**********************************************************
* Notifications
*********************************************************/
.recline-data-explorer .notification-loader {
width: 18px;
margin-left: 5px;
background-image: url(data:image/gif;base64,R0lGODlhEAAQAPQAAP///wAAAPDw8IqKiuDg4EZGRnp6egAAAFhYWCQkJKysrL6+vhQUFJycnAQEBDY2NmhoaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFdyAgAgIJIeWoAkRCCMdBkKtIHIngyMKsErPBYbADpkSCwhDmQCBethRB6Vj4kFCkQPG4IlWDgrNRIwnO4UKBXDufzQvDMaoSDBgFb886MiQadgNABAokfCwzBA8LCg0Egl8jAggGAA1kBIA1BAYzlyILczULC2UhACH5BAkKAAAALAAAAAAQABAAAAV2ICACAmlAZTmOREEIyUEQjLKKxPHADhEvqxlgcGgkGI1DYSVAIAWMx+lwSKkICJ0QsHi9RgKBwnVTiRQQgwF4I4UFDQQEwi6/3YSGWRRmjhEETAJfIgMFCnAKM0KDV4EEEAQLiF18TAYNXDaSe3x6mjidN1s3IQAh+QQJCgAAACwAAAAAEAAQAAAFeCAgAgLZDGU5jgRECEUiCI+yioSDwDJyLKsXoHFQxBSHAoAAFBhqtMJg8DgQBgfrEsJAEAg4YhZIEiwgKtHiMBgtpg3wbUZXGO7kOb1MUKRFMysCChAoggJCIg0GC2aNe4gqQldfL4l/Ag1AXySJgn5LcoE3QXI3IQAh+QQJCgAAACwAAAAAEAAQAAAFdiAgAgLZNGU5joQhCEjxIssqEo8bC9BRjy9Ag7GILQ4QEoE0gBAEBcOpcBA0DoxSK/e8LRIHn+i1cK0IyKdg0VAoljYIg+GgnRrwVS/8IAkICyosBIQpBAMoKy9dImxPhS+GKkFrkX+TigtLlIyKXUF+NjagNiEAIfkECQoAAAAsAAAAABAAEAAABWwgIAICaRhlOY4EIgjH8R7LKhKHGwsMvb4AAy3WODBIBBKCsYA9TjuhDNDKEVSERezQEL0WrhXucRUQGuik7bFlngzqVW9LMl9XWvLdjFaJtDFqZ1cEZUB0dUgvL3dgP4WJZn4jkomWNpSTIyEAIfkECQoAAAAsAAAAABAAEAAABX4gIAICuSxlOY6CIgiD8RrEKgqGOwxwUrMlAoSwIzAGpJpgoSDAGifDY5kopBYDlEpAQBwevxfBtRIUGi8xwWkDNBCIwmC9Vq0aiQQDQuK+VgQPDXV9hCJjBwcFYU5pLwwHXQcMKSmNLQcIAExlbH8JBwttaX0ABAcNbWVbKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICSRBlOY7CIghN8zbEKsKoIjdFzZaEgUBHKChMJtRwcWpAWoWnifm6ESAMhO8lQK0EEAV3rFopIBCEcGwDKAqPh4HUrY4ICHH1dSoTFgcHUiZjBhAJB2AHDykpKAwHAwdzf19KkASIPl9cDgcnDkdtNwiMJCshACH5BAkKAAAALAAAAAAQABAAAAV3ICACAkkQZTmOAiosiyAoxCq+KPxCNVsSMRgBsiClWrLTSWFoIQZHl6pleBh6suxKMIhlvzbAwkBWfFWrBQTxNLq2RG2yhSUkDs2b63AYDAoJXAcFRwADeAkJDX0AQCsEfAQMDAIPBz0rCgcxky0JRWE1AmwpKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICKZzkqJ4nQZxLqZKv4NqNLKK2/Q4Ek4lFXChsg5ypJjs1II3gEDUSRInEGYAw6B6zM4JhrDAtEosVkLUtHA7RHaHAGJQEjsODcEg0FBAFVgkQJQ1pAwcDDw8KcFtSInwJAowCCA6RIwqZAgkPNgVpWndjdyohACH5BAkKAAAALAAAAAAQABAAAAV5ICACAimc5KieLEuUKvm2xAKLqDCfC2GaO9eL0LABWTiBYmA06W6kHgvCqEJiAIJiu3gcvgUsscHUERm+kaCxyxa+zRPk0SgJEgfIvbAdIAQLCAYlCj4DBw0IBQsMCjIqBAcPAooCBg9pKgsJLwUFOhCZKyQDA3YqIQAh+QQJCgAAACwAAAAAEAAQAAAFdSAgAgIpnOSonmxbqiThCrJKEHFbo8JxDDOZYFFb+A41E4H4OhkOipXwBElYITDAckFEOBgMQ3arkMkUBdxIUGZpEb7kaQBRlASPg0FQQHAbEEMGDSVEAA1QBhAED1E0NgwFAooCDWljaQIQCE5qMHcNhCkjIQAh+QQJCgAAACwAAAAAEAAQAAAFeSAgAgIpnOSoLgxxvqgKLEcCC65KEAByKK8cSpA4DAiHQ/DkKhGKh4ZCtCyZGo6F6iYYPAqFgYy02xkSaLEMV34tELyRYNEsCQyHlvWkGCzsPgMCEAY7Cg04Uk48LAsDhRA8MVQPEF0GAgqYYwSRlycNcWskCkApIyEAOwAAAAAAAAAAAA%3D%3D);
display: inline-block;
}
.recline-data-explorer .alert-loader {
position: absolute;
width: 200px;
left: 50%;
margin-left: -100px;
z-index: 10000;
padding: 40px 0px 40px 0px;
margin-top: -10px;
text-align: center;
font-size: 16px;
font-weight: bold;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
border-top: none;
}

View File

@ -1,188 +0,0 @@
/*
IMPORTANT:
In order to preserve the uniform grid appearance, all cell styles need to have padding, margin and border sizes.
No built-in (selected, editable, highlight, flashing, invalid, loading, :focus) or user-specified CSS
classes should alter those!
*/
.recline-slickgrid .slick-header-columns .slick-header-column {
background-color: #e6e6e6;
background-repeat: no-repeat;
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6));
background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6);
background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
color: #333;
font-weight: bold;
border-right: 1px solid #ccc;
border-top: 1px solid #ccc;
border-bottom: 1px solid #bbb;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.recline-slickgrid .slick-header-column:hover, .slick-header-column-active {
}
.recline-slickgrid .slick-header-column.ui-state-default {
height: 26px;
}
.recline-slickgrid .slick-headerrow {
background: #fafafa;
}
.recline-slickgrid .slick-headerrow-column {
background: #fafafa;
border-bottom: 0;
height: 100%;
}
.recline-slickgrid .slick-row.ui-state-active {
background: #F5F7D7;
}
.recline-slickgrid .slick-row {
position: absolute;
background: white;
border: 0px;
line-height: 20px;
}
.recline-slickgrid .slick-row.selected {
z-index: 10;
background: #DFE8F6;
}
.recline-slickgrid .slick-cell {
padding-left: 4px;
padding-right: 4px;
}
.recline-slickgrid .slick-group {
border-bottom: 2px solid silver;
}
.recline-slickgrid .slick-group-toggle {
width: 9px;
height: 9px;
margin-right: 5px;
}
.recline-slickgrid .slick-group-toggle.expanded {
background: url(../images/collapse.gif) no-repeat center center;
}
.recline-slickgrid .slick-group-toggle.collapsed {
background: url(../images/expand.gif) no-repeat center center;
}
.recline-slickgrid .slick-group-totals {
color: gray;
background: white;
}
.recline-slickgrid .slick-cell.selected {
background-color: beige;
}
.recline-slickgrid .slick-cell.active {
border-color: gray;
border-style: solid;
}
.recline-slickgrid .slick-sortable-placeholder {
background: silver !important;
}
.recline-slickgrid .slick-row[row$="1"], .slick-row[row$="3"], .slick-row[row$="5"], .slick-row[row$="7"], .slick-row[row$="9"] {
background: #fafafa;
}
.recline-slickgrid .slick-row.ui-state-active {
background: #F5F7D7;
}
.recline-slickgrid .slick-row.loading {
opacity: 0.5;
filter: alpha(opacity = 50);
}
.recline-slickgrid .slick-cell.invalid {
border-color: red;
}
.recline-slickgrid .slick-row .slick-cell:first-child,
.recline-slickgrid .slick-header {
border-left: 1px solid #ccc;
}
/* add one pixel extra as added one pixel to left border of header */
.recline-slickgrid .slick-row .slick-cell {
margin-right: -1px;
}
/* Slick grid context menu (not part of the recline-slickgrid div) */
.slick-contextmenu {
border-radius: 5px
}
.slick-contextmenu li {
clear: both;
height: 24px;
cursor: pointer;
}
.slick-contextmenu .divider {
cursor: default;
}
.slick-contextmenu > li:hover {
background-color: #0088cc;
}
.slick-contextmenu .divider:hover {
background-color: #E5E5E5;
}
.slick-contextmenu li:hover > label {
color: white;
}
.slick-contextmenu input {
float: left;
margin-left: 15px;
margin-top: 5px;
}
.slick-contextmenu label {
float: left;
margin-right: 15px;
margin-left: 5px;
margin-top: 3px;
color: #555;
cursor: pointer;
}
.recline-slickgrid .recline-row-delete {
font-size: 12px;
padding: 3px;
width: 29px;
height: 18px;
line-height: 13px;
}
.recline-cell-reorder {
font-size: 12px;
padding: 1px;
width: 31px;
height: 14px;
line-height: 13px;
cursor: move;
background: url("../images/drag-handle.png") no-repeat center center;
}

View File

@ -1,3 +0,0 @@
.recline-timeline {
position: relative;
}

View File

@ -1,8 +0,0 @@
<script type="text/javascript">
var newloc = '../app/';
if (window.location.search) {
newloc += window.location.search;
}
newloc += window.location.hash;
window.location.href = newloc;
</script>

View File

@ -1,4 +0,0 @@
Date,Name,Price_Paid,Pricing_Mechanism,Description,Transaction_Type,FDIC_Number,OTS_Number,Type_of_Institution,Total_Assets_Q4_2008,Regulator,City,State,Stock_Symbol,Program,Warrant_Strike_Price,Warrant_Received,Stock_Price_as_of_close_20090604,In_Out_of_Money_as_of_close_20090604,Subsidy_Rate_Estimate_percentage,Subsidy_Rate_Estimate_Date,Subsidy_Rate_Estimate_Source
2009-05-29,AMERICAN PREMIER BANCORP,1800000.00,Par,Preferred Stock w/ Exercised Warrants,Purchase,3175600,,holding company,81126000.00,,Arcadia,CA,,CPP,,,,,,,
2009-05-29,"C.S. BANCSHARES, INC.",24990000.00,Par,Preferred Stock w/ Exercised Warrants,Purchase,1138786,,holding company,197348000.00,,Chillicothe,MO,,CPP,,,,,,,
2009-05-29,CB HOLDING CORP.,4114000.00,Par,Preferred Stock w/ Exercised Warrants,Purchase,3184901,,holding company,164478000.00,,Aledo,IL,,CPP,,,,,,,
1 Date Name Price_Paid Pricing_Mechanism Description Transaction_Type FDIC_Number OTS_Number Type_of_Institution Total_Assets_Q4_2008 Regulator City State Stock_Symbol Program Warrant_Strike_Price Warrant_Received Stock_Price_as_of_close_20090604 In_Out_of_Money_as_of_close_20090604 Subsidy_Rate_Estimate_percentage Subsidy_Rate_Estimate_Date Subsidy_Rate_Estimate_Source
2 2009-05-29 AMERICAN PREMIER BANCORP 1800000.00 Par Preferred Stock w/ Exercised Warrants Purchase 3175600 holding company 81126000.00 Arcadia CA CPP
3 2009-05-29 C.S. BANCSHARES, INC. 24990000.00 Par Preferred Stock w/ Exercised Warrants Purchase 1138786 holding company 197348000.00 Chillicothe MO CPP
4 2009-05-29 CB HOLDING CORP. 4114000.00 Par Preferred Stock w/ Exercised Warrants Purchase 3184901 holding company 164478000.00 Aledo IL CPP

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,94 +0,0 @@
---
layout: container
title: Demos
root: ../
---
<div class="page-header">
<h1>
Demos
</h1>
</div>
<div class="row">
<div class="col-md-4">
<div class="well">
<h3><a href="multiview/">Multiview Demo</a></h3>
<p>See the integrated <a href="multiview/">multiview in action on a
sample dataset</a> - the multiview incorporates most the main views
(grid, graph, map etc) into one integrated view with search, filtering
and field summaries.</p>
</div>
</div>
<div class="col-md-8">
<a href="multiview/"><img src="http://farm8.staticflickr.com/7251/7508402742_03c74a9763_c.jpg" style="width: 100%" /></a>
</div>
</div>
<hr />
<div class="row">
<div class="col-md-4">
<div class="well">
<h3><a href="http://explorer.okfnlabs.org/">Data Explorer</a></h3>
<p>The <a href="http://explorer.okfnlabs.org/">Data Explorer</a> is a full
application for exploring and working with data in your browser. It
utilizes almost every feature of ReclineJS and is the app that ReclineJS
was originally developed to build.</p>
</div>
</div>
<div class="col-md-8">
<a href="http://explorer.okfnlabs.org/"><img src="http://farm8.staticflickr.com/7130/7508402380_c11f52f926_b.jpg" style="width: 100%;" /></a>
</div>
</div>
<hr />
<div class="row">
<div class="col-md-4">
<div class="well">
<h3><a href="http://timeliner.reclinejs.com/">Timeliner</a></h3>
<p>Create timelines quickly and easily using the <a
href="multiview/">Timeliner App created with ReclineJS</a> (<a
href="https://github.com/okfn/timeliner">source code</a>)</p>
</div>
</div>
<div class="col-md-8">
<a href="http://timeliner.reclinejs.com/?backend=gdocs&url=https://docs.google.com/spreadsheet/ccc?key=0Aon3JiuouxLUdFROanhQOVh0NUhyOXNxRDdkc0tEZFE%23gid=0"><img src="http://farm9.staticflickr.com/8285/7508403206_420de3ce5e_b.jpg" style="width: 100%;" /></a>
</div>
</div>
<hr />
<div class="row">
<div class="col-md-4">
<div class="well">
<h3><a href="http://bit.ly/recline-explorer-crime-sf">Crime Maps</a></h3>
<p>See Recline's geo filter and map view capabilities put to good use
exploring crime's in San Francisco. This example shows you the Recline
Data Explorer pre-configured to show thefts near 9th and Mission.</p>
</div>
</div>
<div class="col-md-8">
<a href="http://bit.ly/recline-explorer-crime-sf"><img src="http://farm8.staticflickr.com/7279/7508402914_616326ee3f_z.jpg" /></a>
</div>
</div>
<hr />
<div class="row">
<div class="col-md-4">
<div class="well">
<h3><a href="search/">Search Demo</a></h3>
<p>See how easy it is to build a responsive AJAX-based search interface
to a search backend. It includes full-text search, faceting and ability
to easily customize the display of results.</p>
</div>
</div>
<div class="col-md-8">
<a href="search/"><img src="http://i.imgur.com/AmGx7.png" style="width: 100%;" /></a>
</div>
</div>
<hr />

View File

@ -1,117 +0,0 @@
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();
});
});
// create standard demo dataset
function createDemoDataset() {
var dataset = new recline.Model.Dataset({
records: [
{id: 0, date: '2011-01-01', x: 1, y: 2, z: 3, country: 'DE', title: 'first', lat:52.56, lon:13.40},
{id: 1, date: '2011-02-02', x: 2, y: 4, z: 24, country: 'UK', title: 'second', lat:54.97, lon:-1.60},
{id: 2, date: '2011-03-03', x: 3, y: 6, z: 9, country: 'US', title: 'third', lat:40.00, lon:-75.5},
{id: 3, date: '2011-04-04', x: 4, y: 8, z: 6, country: 'UK', title: 'fourth', lat:57.27, lon:-6.20},
{id: 4, date: '2011-05-04', x: 5, y: 10, z: 15, country: 'UK', title: 'fifth', lat:51.58, lon:0},
{id: 5, date: '2011-06-02', x: 6, y: 12, z: 18, country: 'DE', title: '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: 'title', 'label': 'Title'},
{id: 'lat'},
{id: 'lon'}
]
});
return dataset;
}
// make MultivView
//
// creation / initialization in a function so we can call it again and again
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 fmt = I18nMessages('recline', recline.View.translations);
var views = [
{
id: 'grid',
label: fmt.t('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: 'title', editor: Slick.Editors.Text }
]
}
})
},
{
id: 'graph',
label: fmt.t('Graph'),
view: new recline.View.Graph({
model: dataset
})
},
{
id: 'map',
label: fmt.t('Map'),
view: new recline.View.Map({
model: dataset
})
}
];
var multiView = new recline.View.MultiView({
model: dataset,
el: $el,
state: state,
views: views
});
return multiView;
}

View File

@ -1,33 +0,0 @@
---
layout: container
title: Demos - Multiview
recline-deps: true
root: ../../
---
<style type="text/css">
.recline-slickgrid {
height: 300px;
}
.recline-timeline .vmm-timeline {
height: 550px;
}
.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>
<script type="text/javascript" src="app.js"></script>

View File

@ -1,270 +0,0 @@
// (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)!
// ## Our main loop - on document ready
jQuery(function($) {
var $el = $('.search-here');
// ### Overview
//
// We have a slightly more complex setup than is needed to allow for using
// this demo with different backends
//
// There are 2 alternatives: more complex and a simpler one
//
// If you just want to see how this work skip to the simple case ...
// ### 1. More complex - use data from a backend configured in query string
// Check for config from url query string
var config = recline.View.parseQueryString(decodeURIComponent(window.location.search));
if (config.backend) {
// If we had it hand off to our more complex example setup
setupMoreComplexExample(config);
return;
}
// ### 2. The simple example case
//
// We will just set up from some example local data (at the bottom of thile file)
// #### Create our Recline Dataset from sample local data
var dataset = new recline.Model.Dataset({
records: sampleData
});
// #### Custom template
//
// Create a custom template for rendering the records
var template = ' \
<div class="record"> \
<h3> \
{{title}} <em>by {{Author}}</em> \
</h3> \
<p>{{description}}</p> \
<p><code>${{price}}</code></p> \
</div> \
';
// #### Set up the search View (using custom template)
var searchView = new SearchView({
el: $el,
model: dataset,
template: template
});
searchView.render();
// #### Optional - we configure the initial query a bit and set up facets
dataset.queryState.set({
size: 10
},
{silent: true}
);
dataset.queryState.addFacet('Author');
// #### Finally - now do the first query
//
// After this point the Search View will take over handling queries!
dataset.query();
});
// ## Simple Search View
//
// 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
//
// It also provides simple support for customization e.g. of template for list of results
//
// 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
// });
var SearchView = Backbone.View.extend({
initialize: function(options) {
this.el = $(this.el);
_.bindAll(this, 'render');
this.recordTemplate = options.template;
// Every time we do a search the recline.Dataset.records Backbone
// collection will get reset. We want to re-render each time!
this.model.records.bind('reset', this.render);
this.templateResults = options.template;
},
// overall template for this view
template: ' \
<div class="controls"> \
<div class="query-here"></div> \
</div> \
<div class="total"><h2><span></span> records found</h2></div> \
<div class="body"> \
<div class="sidebar"></div> \
<div class="results"> \
{{{results}}} \
</div> \
</div> \
<div class="pager-here"></div> \
',
// render the view
render: function() {
var results = '';
if (_.isFunction(this.templateResults)) {
var results = _.map(this.model.records.toJSON(), this.templateResults).join('\n');
} else {
// templateResults is just for one result ...
var tmpl = '{{#records}}' + this.templateResults + '{{/records}}';
var results = Mustache.render(tmpl, {
records: this.model.records.toJSON()
});
}
var html = Mustache.render(this.template, {
results: results
});
this.el.html(html);
// Set the total records found info
this.el.find('.total span').text(this.model.recordCount);
// ### Now setup all the extra mini-widgets
//
// Facets, Pager, QueryEditor etc
var view = new recline.View.FacetViewer({
model: this.model
});
view.render();
this.el.find('.sidebar').append(view.el);
var pager = new recline.View.Pager({
model: this.model
});
this.el.find('.pager-here').append(pager.el);
var queryEditor = new recline.View.QueryEditor({
model: this.model.queryState
});
this.el.find('.query-here').append(queryEditor.el);
}
});
// --------------------------------------------------------
// ## Custom code very specific to this demo
// e.g. to provide custom templates for the google doc and openspending examples
// ### Handle case where we get data from a specific backend
//
// Includes providing custom templates
function setupMoreComplexExample(config) {
var $el = $('.search-here');
var dataset = new recline.Model.Dataset(config);
// async as may be fetching remote
dataset.fetch().done(function() {
var template = templates[dataset.get('url')] || templates['generic'];
var searchView = new SearchView({
el: $el,
model: dataset,
template: template
});
searchView.render();
dataset.queryState.set({
size: 5
},
{silent: true}
);
if (dataset.get('url') in templates) {
// for gdocs example
dataset.queryState.addFacet('cause');
}
dataset.query();
});
};
var templates = {
// generic template function
'generic': function(record) {
var template = '<div class="record"> \
<ul> \
{{#data}} \
<li>{{key}}: {{value}}</li> \
{{/data}} \
</ul> \
</div> \
';
var data = _.map(_.keys(record), function(key) {
return { key: key, value: record[key] };
});
return Mustache.render(template, {
data: data
});
},
'https://docs.google.com/spreadsheet/ccc?key=0Aon3JiuouxLUdExXSTl2Y01xZEszOTBFZjVzcGtzVVE': function(record) {
var template = '<div class="record"> \
<h3> \
{{record.incidentsite}} &ndash; {{record.datereported}} &ndash; {{record.estimatedspillvolumebbl}} barrels \
</h3> \
<ul> \
{{#data}} \
<li>{{key}}: {{value}}</li> \
{{/data}} \
</ul> \
</div> \
';
var data = [];
_.each(_.keys(record), function(key) {
data.push({ key: key, value: record[key] });
});
return Mustache.render(template, {
record: record,
data: data
});
}
}
var sampleData = [
{
title: 'War and Peace',
description: 'The epic tale of love, war and history',
Author: 'Tolstoy',
price: 7.99
},
{
title: 'Anna Karenina',
description: 'How things go wrong in love and ultimately lead to suicide. This is why you should not have affairs, girls!',
Author: 'Tolstoy',
price: 8.50
},
{
title: "Fathers and Sons",
description: "Another 19th century Russian novel",
Author: "Turgenev",
price: 11
}
];
var formatAmount = function (num) {
var billion = 1000000000;
var million = 1000000;
var thousand = 1000;
var numabs = Math.abs(num);
if (numabs > billion) {
return (num / billion).toFixed(0) + 'bn';
}
if (numabs > (million / 2)) {
return (num / million).toFixed(0) + 'm';
}
if (numabs > thousand) {
return (num / thousand).toFixed(0) + 'k';
} else {
return num.toFixed(0);
}
};

View File

@ -1,84 +0,0 @@
---
layout: container
title: Demos - Search
recline-deps: true
root: ../../
---
<style type="text/css">
.info {
margin-bottom: 10px;
}
/***************** Search Section ****************/
.record {
border-bottom: #eee 1px solid;
padding: 5px;
}
.controls .query-here {
width: 510px;
margin: auto;
}
.controls .query-here .text-query input {
width: 400px;
/* fix offset bug ...*/
margin-left: -4px;
}
.pager-here {
width: 230px;
margin: auto;
}
.body {
clear: both;
}
.results {
margin-right: 290px;
border-right: #eee 1px solid;
padding-right: 20px;
}
.sidebar {
height: 100%;
width: 270px;
float: right;
padding-left: 10px;
}
ul.facet-items {
list-style-type: none;
margin-left: 0px;
padding: 0px;
}
.record ul {
list-style-type: none;
margin-left: 0;
}
.recline-query-editor {
border-right: none;
}
</style>
<div class="page-header">
<h1>Recline Search Demo</h1>
</div>
<div class="info">
<p>This demo shows how Recline can be used to build a search app. It includes faceting as well as search. You can find the <a href="demo.search.app.js">source javascript here</a> (plus <a href="{{page.root}}/docs/src/demo.search.app.html">prettified version of source for readability</a>) &ndash; please feel free to reuse!</p>
<p>The default setup uses local example data but you can also connect directly to any other <a href="{{page.root}}/docs/backends.html">backend supported by Recline</a>, for example SOLR, ElasticSearch or even a google docs spreadsheet. Here's an example <a href="?backend=gdocs&amp;url=https://docs.google.com/spreadsheet/ccc?key=0Aon3JiuouxLUdExXSTl2Y01xZEszOTBFZjVzcGtzVVE">running against a GDocs spreadsheet (Oil spills in the Niger Delta)</a>.</p>
</div>
<hr />
<div class="search-here"></div>
<div style="clear: both;"></div>
<script type="text/javascript" src="demo.search.app.js"></script>

796
dist/recline.css vendored
View File

@ -1,796 +0,0 @@
.recline-flot .graph {
height: 500px;
overflow: hidden;
}
.recline-flot .legend table {
width: auto;
margin-bottom: 0;
}
.recline-flot .legend td {
padding: 5px;
line-height: 13px;
}
.recline-flot .graph .alert {
width: 450px;
}
#recline-flot-tooltip {
position: absolute;
background-color: #FEE;
color: #000000;
opacity: 0.8;
border: 1px solid #fdd;
}
/**********************************************************
* (Data) Grid
*********************************************************/
table.recline-grid {
table-layout: fixed;
width: 100%;
}
.recline-grid .btn-group .dropdown-toggle {
padding: 1px 3px;
line-height: auto;
}
.recline-grid td, .recline-grid th {
border-left: 1px solid #ccc;
padding: 3px 4px;
text-align: left;
word-wrap: break-word;
white-space: normal;
}
.recline-grid tbody tr {
vertical-align: top;
border-bottom: solid 1px #ccc;
}
.recline-grid tbody tr:last-child {
border-bottom: 1px solid #ccc;
}
.recline-grid tbody td:last-child {
border-right: 1px solid #ccc;
}
/* direct borrowing from twitter buttons */
.recline-grid th {
background-color: #e6e6e6;
background-repeat: no-repeat;
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6));
background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6);
background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
color: #333;
border: 1px solid #ccc;
border-bottom-color: #bbb;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-webkit-transition: 0.1s linear all;
-moz-transition: 0.1s linear all;
-ms-transition: 0.1s linear all;
-o-transition: 0.1s linear all;
transition: 0.1s linear all;
}
/**********************************************************
* Fixed Header - http://www.imaputz.com/cssStuff/bigFourVersion.html
*********************************************************/
div.table-container {
overflow: auto;
}
/* Reset overflow value to hidden for all non-IE browsers. */
html>body div.table-container {
overflow: hidden;
}
thead.fixed-header tr {
overflow-x: hidden;
}
/* set table header to a fixed position. WinIE 6.x only */
/* In WinIE 6.x, any element with a position property set to relative and is a child of */
/* an element that has an overflow property set, the relative value translates into fixed. */
/* Ex: parent element DIV with a class of table-container has an overflow property set to auto */
thead.fixed-header tr {
position: relative
}
/* set THEAD element to have block level attributes. All other non-IE browsers */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
html>body thead.fixed-header tr {
display: block
}
/* define the table content to be scrollable */
/* set TBODY element to have block level attributes. All other non-IE browsers */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
/* induced side effect is that child TDs no longer accept width: auto */
tbody.scroll-content {
display: block;
max-height: 500px;
overflow: auto;
}
/**********************************************************
* Data Table Menus
*********************************************************/
.column-header-menu, a.root-header-menu {
float: right;
}
div.data-table-cell-content {
line-height: 1.2;
color: #222;
position: relative;
}
div.data-table-cell-content-numeric {
text-align: right;
}
a.data-table-cell-edit {
position: absolute;
top: 0;
right: 0;
display: block;
width: 25px;
height: 16px;
text-decoration: none;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAQCAYAAABUWyyMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTNEODNFMjVEMDA5MTFERjk5NzhEQzZDRDUwRkEzMUEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTNEODNFMjZEMDA5MTFERjk5NzhEQzZDRDUwRkEzMUEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5M0Q4M0UyM0QwMDkxMURGOTk3OERDNkNENTBGQTMxQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5M0Q4M0UyNEQwMDkxMURGOTk3OERDNkNENTBGQTMxQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpApVmcAAAKVSURBVHjaYvz//z/DcAAsIGLaxjf2QKoLiM2oaPYpIC7L8hc5COI4F9+hmR17e1UOskAFVgCxBJUDyQxqriQ97GCCCpBkATCUGQxVOTHY7KyMDFoKHMhKJXCwCQJgKDNEOAlisHk5mRh8LPgw7GChNEg2HfvI8OnbPzDbwYAH6BkmhmsPflA12EtnPmN4/vY3mF0YKgb2zJYTn5CV/EfxiKgAC4O7CS8DHzczw5PXvxl2nv7E8PP3fxTx87e/o1hipMrFcOfZT6BmVgYZUTawmKUWN8Pxa1+xOkpNhp2hLk6CQVKYleHcrW8MTYteMHz+/g9FfMW+9yh6Ih0FGA5e/MLAAIx5IzUusFiqtzDD7K1vYUpcmZA1+FnxM7z++AccyqBkAgphmMPY2ZiAHvsMFkcGMkAPgMQ+ff3L8PPXPzD++O0vztDtypBmuPXkJziUebiYwSEMcxiID/IYiEYJLKDjQWLP3v1h+AI0G4RhMQQF5UzoDvr5CxIDoJhQlmKHy527/Y3hLjDkD4BCBgsAxSAoiYEwrqQFchAoWcBiAOQge30euBwoJkAh37/6FVb9oBgEeQCE0ZKWC8488vj1LzCmJTgLTKZn0ZIquYAJOURBsQDKB68//GHgYEWkOlBMgPICKIYcoCGIC4BiFRSDuEIUFBtSQizg5AWKHRgAxQSoZALFECy54QKgZAbLKxgegZVAfFxM4LyiLMUGTPeQ0ujAhS9gz7mb8sI9iisWQclSG7UIRgFlM56CM3R3uhTY0bC0DkpOtx//AGd4mEdxxSIoWaIVwQyMoCYKsGanWTsFWM8wQmt2mtkBqmdgMfKCRna8wMGmth2MMI/EAfEdKltwB2ouAz3sYBwurV8mhmECAAIMAEe3EkMWh/DvAAAAAElFTkSuQmCC);
background-repeat: no-repeat;
visibility: hidden;
}
a.data-table-cell-edit:hover {
background-position: -25px 0px;
}
.recline-grid td:hover .data-table-cell-edit {
visibility: visible;
}
div.data-table-cell-content-numeric > a.data-table-cell-edit {
left: 0px;
right: auto;
}
.data-table-value-nonstring {
color: #282;
}
.data-table-error {
color: red;
}
.data-table-cell-editor-editor {
overflow: hidden;
display: block;
width: 98%;
height: 3em;
font-family: monospace;
margin: 3px 0;
}
.data-table-cell-copypaste-editor {
overflow: hidden;
display: block;
width: 98%;
height: 10em;
font-family: monospace;
margin: 3px 0;
}
.data-table-cell-editor-action {
float: left;
vertical-align: bottom;
text-align: center;
}
.data-table-cell-editor-key {
font-size: 0.8em;
color: #999;
}
/**********************************************************
* Read-only mode
*********************************************************/
.recline-read-only .recline-grid .write-op,
.recline-read-only .recline-grid a.data-table-cell-edit
{
display: none;
}
.recline-read-only a.row-header-menu {
display: none;
}
/*************************
* WCAG 2.0
*************************/
.wcag_hide {
position:absolute;
top:0;
left:-10000px;
width:1px;
height:1px;
}
.wcag_hide2 {
clip: rect(1px, 1px, 1px, 1px);
display: block;
position: absolute;
}
.wcag_show_on_focus {
font-size: 0 !important;
}
.wcag_show_on_focus:focus {
font-size: 1em !important;
}
.recline-map .map {
height: 500px;
}
/**********************************************************
* Editor
*********************************************************/
.recline-map .editor {
float: right;
width: 200px;
padding-left: 0px;
margin-left: 10px;
}
.recline-map .editor form {
padding-left: 4px;
}
.recline-map .editor select {
width: 100%;
}
.recline-map .editor .editor-options {
margin-top: 10px;
border-top: 1px solid gray;
padding: 5px 0;
}
.recline-data-explorer .data-view-container {
display: block;
}
.recline-data-explorer .data-view-sidebar {
float: right;
margin-left: 8px;
width: 220px;
}
.recline-data-explorer .header .navigation {
margin-bottom: 8px;
}
.recline-data-explorer .header .navigation,
.recline-data-explorer .header .pagination,
.recline-data-explorer .header .pagination form
{
display: inline;
}
.recline-data-explorer .header .navigation {
float: left;
}
.recline-data-explorer .header .menu-right {
float: right;
margin-left: 5px;
padding-left: 5px;
}
.recline-results-info {
line-height: 35px;
margin-left: 20px;
float: left;
}
.recline-data-explorer .data-view-sidebar > div {
margin-top: 5px;
margin-bottom: 10px;
}
.recline-data-explorer .radio,
.recline-data-explorer .checkbox {
padding-left: 20px;
}
.recline-data-explorer .editor-update-map {
margin: 30px 0px 20px 0px;
}
.recline-data-explorer label {
font-weight: normal;
}
/**********************************************************
* Query Editor
*********************************************************/
.recline-query-editor {
float: right;
height: 35px;
padding-right: 5px;
margin-right: 5px;
border-right: solid 2px #ddd;
}
.header .input-prepend {
margin-bottom: auto;
}
.header .add-on {
float: left;
}
/* needed for Chrome but not FF */
.header .add-on {
margin-left: -27px;
}
/* needed for FF but not chrome */
.header .input-prepend {
vertical-align: top;
}
.recline-query-editor form button {
vertical-align: top;
}
/* label for screen reader */
.recline-query-editor .form-inline label {
position: absolute;
top:0;
left:-9999px
}
/**********************************************************
* Pager
*********************************************************/
.recline-pager {
float: left;
margin: auto;
display: block;
margin-left: 20px;
}
.recline-pager .pagination li {
display: inline-block;
}
.recline-pager .pagination label {
display:none;
}
.recline-pager .pagination input {
width: 40px;
height: 25px;
padding: 2px 4px;
margin: 0;
margin-top: -2px;
border: 1px solid #cccccc;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
transition: border linear 0.2s, box-shadow linear 0.2s;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
-webkit-border-radius: 4px;
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
-moz-border-radius: 4px;
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
}
.recline-pager .pagination a {
float: none;
margin-left: -5px;
color: #555;
}
.recline-pager .pagination .page-range {
height: 34px;
padding: 5px 8px;
margin-left: -5px;
border: 1px solid #ddd;
}
.recline-pager .pagination .page-range a {
padding: 0px 12px;
border: none;
}
.recline-pager .pagination .page-range a:hover {
background-color: #ffffff;
}
.recline-pager .pagination > li:first-child > a {
border-bottom-left-radius: 4px;
border-top-left-radius: 4px;
border-bottom-right-radius: 0px;
border-top-right-radius: 0px;
height: 34px;
}
.recline-pager .pagination > li:last-child > a {
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
border-bottom-left-radius: 0px;
border-top-left-radius: 0px;
height: 34px;
}
/**********************************************************
* Filter Editor
*********************************************************/
.recline-filter-editor {
padding: 8px;
display: none;
}
.recline-filter-editor .filters {
margin: 20px 0px;
}
.recline-filter-editor h3 {
margin-top: 4px;
}
.recline-filter-editor .filter {
margin-top: 20px;
}
.recline-filter-editor .filter .form-group {
margin-bottom: 0px;
}
.recline-filter-editor .filter input,
.recline-filter-editor .filter label {
margin: 0px;
}
.recline-filter-editor .js-edit button {
margin: 25px 0px 0px 0px;
}
.recline-filter-editor .filter-term a {
font-size: 18px;
}
.recline-filter-editor input,
.recline-filter-editor select
{
width: 175px;
}
.recline-filter-editor input {
margin-top: 0.5em;
margin-bottom: 10px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 1px solid #cccccc;
}
.recline-filter-editor label {
font-weight: normal;
display: block;
}
.recline-filter-editor legend {
margin-bottom: 5px;
}
.recline-filter-editor .add-filter {
margin-top: 1em;
margin-bottom: 2em;
}
.recline-filter-editor .update-filter {
margin-top: 1em;
}
/**********************************************************
* Fields Widget
*********************************************************/
.recline-fields-view {
display: none;
}
.recline-fields-view .fields-list {
padding: 0;
}
.recline-fields-view .panel {
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
}
.recline-fields-view .panel-group h3 {
padding-left: 10px;
}
.recline-fields-view .fields-list .panel-heading {
padding: 2px 5px;
margin: 1px 0px 1px 5px;
}
.recline-fields-view .panel a,
.recline-fields-view .panel h4 {
display: inline;
}
.recline-fields-view .panel a {
padding: 0;
}
.recline-fields-view .panel h4 {
word-wrap: break-word
}
.recline-fields-view .clear {
clear: both;
}
.recline-fields-view .facet-items {
list-style-type: none;
margin-left: 0;
}
.recline-fields-view .facet-item .term {
font-weight: bold;
}
.recline-fields-view .facet-item .count {
}
/**********************************************************
* Notifications
*********************************************************/
.recline-data-explorer .notification-loader {
width: 18px;
margin-left: 5px;
background-image: url(data:image/gif;base64,R0lGODlhEAAQAPQAAP///wAAAPDw8IqKiuDg4EZGRnp6egAAAFhYWCQkJKysrL6+vhQUFJycnAQEBDY2NmhoaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFdyAgAgIJIeWoAkRCCMdBkKtIHIngyMKsErPBYbADpkSCwhDmQCBethRB6Vj4kFCkQPG4IlWDgrNRIwnO4UKBXDufzQvDMaoSDBgFb886MiQadgNABAokfCwzBA8LCg0Egl8jAggGAA1kBIA1BAYzlyILczULC2UhACH5BAkKAAAALAAAAAAQABAAAAV2ICACAmlAZTmOREEIyUEQjLKKxPHADhEvqxlgcGgkGI1DYSVAIAWMx+lwSKkICJ0QsHi9RgKBwnVTiRQQgwF4I4UFDQQEwi6/3YSGWRRmjhEETAJfIgMFCnAKM0KDV4EEEAQLiF18TAYNXDaSe3x6mjidN1s3IQAh+QQJCgAAACwAAAAAEAAQAAAFeCAgAgLZDGU5jgRECEUiCI+yioSDwDJyLKsXoHFQxBSHAoAAFBhqtMJg8DgQBgfrEsJAEAg4YhZIEiwgKtHiMBgtpg3wbUZXGO7kOb1MUKRFMysCChAoggJCIg0GC2aNe4gqQldfL4l/Ag1AXySJgn5LcoE3QXI3IQAh+QQJCgAAACwAAAAAEAAQAAAFdiAgAgLZNGU5joQhCEjxIssqEo8bC9BRjy9Ag7GILQ4QEoE0gBAEBcOpcBA0DoxSK/e8LRIHn+i1cK0IyKdg0VAoljYIg+GgnRrwVS/8IAkICyosBIQpBAMoKy9dImxPhS+GKkFrkX+TigtLlIyKXUF+NjagNiEAIfkECQoAAAAsAAAAABAAEAAABWwgIAICaRhlOY4EIgjH8R7LKhKHGwsMvb4AAy3WODBIBBKCsYA9TjuhDNDKEVSERezQEL0WrhXucRUQGuik7bFlngzqVW9LMl9XWvLdjFaJtDFqZ1cEZUB0dUgvL3dgP4WJZn4jkomWNpSTIyEAIfkECQoAAAAsAAAAABAAEAAABX4gIAICuSxlOY6CIgiD8RrEKgqGOwxwUrMlAoSwIzAGpJpgoSDAGifDY5kopBYDlEpAQBwevxfBtRIUGi8xwWkDNBCIwmC9Vq0aiQQDQuK+VgQPDXV9hCJjBwcFYU5pLwwHXQcMKSmNLQcIAExlbH8JBwttaX0ABAcNbWVbKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICSRBlOY7CIghN8zbEKsKoIjdFzZaEgUBHKChMJtRwcWpAWoWnifm6ESAMhO8lQK0EEAV3rFopIBCEcGwDKAqPh4HUrY4ICHH1dSoTFgcHUiZjBhAJB2AHDykpKAwHAwdzf19KkASIPl9cDgcnDkdtNwiMJCshACH5BAkKAAAALAAAAAAQABAAAAV3ICACAkkQZTmOAiosiyAoxCq+KPxCNVsSMRgBsiClWrLTSWFoIQZHl6pleBh6suxKMIhlvzbAwkBWfFWrBQTxNLq2RG2yhSUkDs2b63AYDAoJXAcFRwADeAkJDX0AQCsEfAQMDAIPBz0rCgcxky0JRWE1AmwpKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICKZzkqJ4nQZxLqZKv4NqNLKK2/Q4Ek4lFXChsg5ypJjs1II3gEDUSRInEGYAw6B6zM4JhrDAtEosVkLUtHA7RHaHAGJQEjsODcEg0FBAFVgkQJQ1pAwcDDw8KcFtSInwJAowCCA6RIwqZAgkPNgVpWndjdyohACH5BAkKAAAALAAAAAAQABAAAAV5ICACAimc5KieLEuUKvm2xAKLqDCfC2GaO9eL0LABWTiBYmA06W6kHgvCqEJiAIJiu3gcvgUsscHUERm+kaCxyxa+zRPk0SgJEgfIvbAdIAQLCAYlCj4DBw0IBQsMCjIqBAcPAooCBg9pKgsJLwUFOhCZKyQDA3YqIQAh+QQJCgAAACwAAAAAEAAQAAAFdSAgAgIpnOSonmxbqiThCrJKEHFbo8JxDDOZYFFb+A41E4H4OhkOipXwBElYITDAckFEOBgMQ3arkMkUBdxIUGZpEb7kaQBRlASPg0FQQHAbEEMGDSVEAA1QBhAED1E0NgwFAooCDWljaQIQCE5qMHcNhCkjIQAh+QQJCgAAACwAAAAAEAAQAAAFeSAgAgIpnOSoLgxxvqgKLEcCC65KEAByKK8cSpA4DAiHQ/DkKhGKh4ZCtCyZGo6F6iYYPAqFgYy02xkSaLEMV34tELyRYNEsCQyHlvWkGCzsPgMCEAY7Cg04Uk48LAsDhRA8MVQPEF0GAgqYYwSRlycNcWskCkApIyEAOwAAAAAAAAAAAA%3D%3D);
display: inline-block;
}
.recline-data-explorer .alert-loader {
position: absolute;
width: 200px;
left: 50%;
margin-left: -100px;
z-index: 10000;
padding: 40px 0px 40px 0px;
margin-top: -10px;
text-align: center;
font-size: 16px;
font-weight: bold;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
border-top: none;
}
/*
IMPORTANT:
In order to preserve the uniform grid appearance, all cell styles need to have padding, margin and border sizes.
No built-in (selected, editable, highlight, flashing, invalid, loading, :focus) or user-specified CSS
classes should alter those!
*/
.recline-slickgrid .slick-header-columns .slick-header-column {
background-color: #e6e6e6;
background-repeat: no-repeat;
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6));
background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6);
background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
color: #333;
font-weight: bold;
border-right: 1px solid #ccc;
border-top: 1px solid #ccc;
border-bottom: 1px solid #bbb;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.recline-slickgrid .slick-header-column:hover, .slick-header-column-active {
}
.recline-slickgrid .slick-header-column.ui-state-default {
height: 26px;
}
.recline-slickgrid .slick-headerrow {
background: #fafafa;
}
.recline-slickgrid .slick-headerrow-column {
background: #fafafa;
border-bottom: 0;
height: 100%;
}
.recline-slickgrid .slick-row.ui-state-active {
background: #F5F7D7;
}
.recline-slickgrid .slick-row {
position: absolute;
background: white;
border: 0px;
line-height: 20px;
}
.recline-slickgrid .slick-row.selected {
z-index: 10;
background: #DFE8F6;
}
.recline-slickgrid .slick-cell {
padding-left: 4px;
padding-right: 4px;
}
.recline-slickgrid .slick-group {
border-bottom: 2px solid silver;
}
.recline-slickgrid .slick-group-toggle {
width: 9px;
height: 9px;
margin-right: 5px;
}
.recline-slickgrid .slick-group-toggle.expanded {
background: url(../images/collapse.gif) no-repeat center center;
}
.recline-slickgrid .slick-group-toggle.collapsed {
background: url(../images/expand.gif) no-repeat center center;
}
.recline-slickgrid .slick-group-totals {
color: gray;
background: white;
}
.recline-slickgrid .slick-cell.selected {
background-color: beige;
}
.recline-slickgrid .slick-cell.active {
border-color: gray;
border-style: solid;
}
.recline-slickgrid .slick-sortable-placeholder {
background: silver !important;
}
.recline-slickgrid .slick-row[row$="1"], .slick-row[row$="3"], .slick-row[row$="5"], .slick-row[row$="7"], .slick-row[row$="9"] {
background: #fafafa;
}
.recline-slickgrid .slick-row.ui-state-active {
background: #F5F7D7;
}
.recline-slickgrid .slick-row.loading {
opacity: 0.5;
filter: alpha(opacity = 50);
}
.recline-slickgrid .slick-cell.invalid {
border-color: red;
}
.recline-slickgrid .slick-row .slick-cell:first-child,
.recline-slickgrid .slick-header {
border-left: 1px solid #ccc;
}
/* add one pixel extra as added one pixel to left border of header */
.recline-slickgrid .slick-row .slick-cell {
margin-right: -1px;
}
/* Slick grid context menu (not part of the recline-slickgrid div) */
.slick-contextmenu {
border-radius: 5px
}
.slick-contextmenu li {
clear: both;
height: 24px;
cursor: pointer;
}
.slick-contextmenu .divider {
cursor: default;
}
.slick-contextmenu > li:hover {
background-color: #0088cc;
}
.slick-contextmenu .divider:hover {
background-color: #E5E5E5;
}
.slick-contextmenu li:hover > label {
color: white;
}
.slick-contextmenu input {
float: left;
margin-left: 15px;
margin-top: 5px;
}
.slick-contextmenu label {
float: left;
margin-right: 15px;
margin-left: 5px;
margin-top: 3px;
color: #555;
cursor: pointer;
}
.recline-slickgrid .recline-row-delete {
font-size: 12px;
padding: 3px;
width: 29px;
height: 18px;
line-height: 13px;
}
.recline-cell-reorder {
font-size: 12px;
padding: 1px;
width: 31px;
height: 14px;
line-height: 13px;
cursor: move;
background: url("../images/drag-handle.png") no-repeat center center;
}
.recline-timeline {
position: relative;
}

View File

@ -1,896 +0,0 @@
// # Recline Backbone Models
this.recline = this.recline || {};
this.recline.Model = this.recline.Model || {};
(function(my) {
"use strict";
// use either jQuery or Underscore Deferred depending on what is available
var Deferred = (typeof jQuery !== "undefined" && jQuery.Deferred) || _.Deferred;
// ## <a id="dataset">Dataset</a>
my.Dataset = Backbone.Model.extend({
constructor: function Dataset() {
Backbone.Model.prototype.constructor.apply(this, arguments);
},
// ### initialize
initialize: function() {
var self = this;
_.bindAll(this, 'query');
this.backend = null;
if (this.get('backend')) {
this.backend = this._backendFromString(this.get('backend'));
} else { // try to guess backend ...
if (this.get('records')) {
this.backend = recline.Backend.Memory;
}
}
this.fields = new my.FieldList();
this.records = new my.RecordList();
this._changes = {
deletes: [],
updates: [],
creates: []
};
this.facets = new my.FacetList();
this.recordCount = null;
this.queryState = new my.Query();
this.queryState.bind('change facet:add', function () {
self.query(); // We want to call query() without any arguments.
});
// store is what we query and save against
// store will either be the backend or be a memory store if Backend fetch
// tells us to use memory store
this._store = this.backend;
// if backend has a handleQueryResultFunction, use that
this._handleResult = (this.backend != null && _.has(this.backend, 'handleQueryResult')) ?
this.backend.handleQueryResult : this._handleQueryResult;
if (this.backend == recline.Backend.Memory) {
this.fetch();
}
},
sync: function(method, model, options) {
return this.backend.sync(method, model, options);
},
// ### fetch
//
// Retrieve dataset and (some) records from the backend.
fetch: function() {
var self = this;
var dfd = new Deferred();
if (this.backend !== recline.Backend.Memory) {
this.backend.fetch(this.toJSON())
.done(handleResults)
.fail(function(args) {
dfd.reject(args);
});
} else {
// special case where we have been given data directly
handleResults({
records: this.get('records'),
fields: this.get('fields'),
useMemoryStore: true
});
}
function handleResults(results) {
// if explicitly given the fields
// (e.g. var dataset = new Dataset({fields: fields, ...})
// use that field info over anything we get back by parsing the data
// (results.fields)
var fields = self.get('fields') || results.fields;
var out = self._normalizeRecordsAndFields(results.records, fields);
if (results.useMemoryStore) {
self._store = new recline.Backend.Memory.Store(out.records, out.fields);
}
self.set(results.metadata);
self.fields.reset(out.fields);
self.query()
.done(function() {
dfd.resolve(self);
})
.fail(function(args) {
dfd.reject(args);
});
}
return dfd.promise();
},
// ### _normalizeRecordsAndFields
//
// Get a proper set of fields and records from incoming set of fields and records either of which may be null or arrays or objects
//
// e.g. fields = ['a', 'b', 'c'] and records = [ [1,2,3] ] =>
// fields = [ {id: a}, {id: b}, {id: c}], records = [ {a: 1}, {b: 2}, {c: 3}]
_normalizeRecordsAndFields: function(records, fields) {
// if no fields get them from records
if (!fields && records && records.length > 0) {
// records is array then fields is first row of records ...
if (records[0] instanceof Array) {
fields = records[0];
records = records.slice(1);
} else {
fields = _.map(_.keys(records[0]), function(key) {
return {id: key};
});
}
}
// fields is an array of strings (i.e. list of field headings/ids)
if (fields && fields.length > 0 && (fields[0] === null || typeof(fields[0]) != 'object')) {
// Rename duplicate fieldIds as each field name needs to be
// unique.
var seen = {};
fields = _.map(fields, function(field, index) {
if (field === null) {
field = '';
} else {
field = field.toString();
}
// cannot use trim as not supported by IE7
var fieldId = field.replace(/^\s+|\s+$/g, '');
if (fieldId === '') {
fieldId = '_noname_';
field = fieldId;
}
while (fieldId in seen) {
seen[field] += 1;
fieldId = field + seen[field];
}
if (!(field in seen)) {
seen[field] = 0;
}
// TODO: decide whether to keep original name as label ...
// return { id: fieldId, label: field || fieldId }
return { id: fieldId };
});
}
// records is provided as arrays so need to zip together with fields
// NB: this requires you to have fields to match arrays
if (records && records.length > 0 && records[0] instanceof Array) {
records = _.map(records, function(doc) {
var tmp = {};
_.each(fields, function(field, idx) {
tmp[field.id] = doc[idx];
});
return tmp;
});
}
return {
fields: fields,
records: records
};
},
save: function() {
var self = this;
// TODO: need to reset the changes ...
return this._store.save(this._changes, this.toJSON());
},
// ### query
//
// AJAX method with promise API to get records from the backend.
//
// It will query based on current query state (given by this.queryState)
// updated by queryObj (if provided).
//
// Resulting RecordList are used to reset this.records and are
// also returned.
query: function(queryObj) {
var self = this;
var dfd = new Deferred();
this.trigger('query:start');
if (queryObj) {
var attributes = queryObj;
if (queryObj instanceof my.Query) {
attributes = queryObj.toJSON();
}
this.queryState.set(attributes, {silent: true});
}
var actualQuery = this.queryState.toJSON();
this._store.query(actualQuery, this.toJSON())
.done(function(queryResult) {
self._handleResult(queryResult);
self.trigger('query:done');
dfd.resolve(self.records);
})
.fail(function(args) {
self.trigger('query:fail', args);
dfd.reject(args);
});
return dfd.promise();
},
_handleQueryResult: function(queryResult) {
var self = this;
self.recordCount = queryResult.total;
var docs = _.map(queryResult.hits, function(hit) {
var _doc = new my.Record(hit);
_doc.fields = self.fields;
_doc.bind('change', function(doc) {
self._changes.updates.push(doc.toJSON());
});
_doc.bind('destroy', function(doc) {
self._changes.deletes.push(doc.toJSON());
});
return _doc;
});
self.records.reset(docs);
if (queryResult.facets) {
var facets = _.map(queryResult.facets, function(facetResult, facetId) {
facetResult.id = facetId;
return new my.Facet(facetResult);
});
self.facets.reset(facets);
}
},
toTemplateJSON: function() {
var data = this.toJSON();
data.recordCount = this.recordCount;
data.fields = this.fields.toJSON();
return data;
},
// ### getFieldsSummary
//
// Get a summary for each field in the form of a `Facet`.
//
// @return null as this is async function. Provides deferred/promise interface.
getFieldsSummary: function() {
var self = this;
var query = new my.Query();
query.set({size: 0});
this.fields.each(function(field) {
query.addFacet(field.id);
});
var dfd = new Deferred();
this._store.query(query.toJSON(), this.toJSON()).done(function(queryResult) {
if (queryResult.facets) {
_.each(queryResult.facets, function(facetResult, facetId) {
facetResult.id = facetId;
var facet = new my.Facet(facetResult);
// TODO: probably want replace rather than reset (i.e. just replace the facet with this id)
self.fields.get(facetId).facets.reset(facet);
});
}
dfd.resolve(queryResult);
});
return dfd.promise();
},
// Deprecated (as of v0.5) - use record.summary()
recordSummary: function(record) {
return record.summary();
},
// ### _backendFromString(backendString)
//
// Look up a backend module from a backend string (look in recline.Backend)
_backendFromString: function(backendString) {
var backend = null;
if (recline && recline.Backend) {
_.each(_.keys(recline.Backend), function(name) {
if (name.toLowerCase() === backendString.toLowerCase()) {
backend = recline.Backend[name];
}
});
}
return backend;
}
});
// ## <a id="record">A Record</a>
//
// A single record (or row) in the dataset
my.Record = Backbone.Model.extend({
constructor: function Record() {
Backbone.Model.prototype.constructor.apply(this, arguments);
},
// ### initialize
//
// Create a Record
//
// You usually will not do this directly but will have records created by
// Dataset e.g. in query method
//
// Certain methods require presence of a fields attribute (identical to that on Dataset)
initialize: function() {
_.bindAll(this, 'getFieldValue');
},
// ### getFieldValue
//
// For the provided Field get the corresponding rendered computed data value
// for this record.
//
// NB: if field is undefined a default '' value will be returned
getFieldValue: function(field) {
var val = this.getFieldValueUnrendered(field);
if (field && !_.isUndefined(field.renderer)) {
val = field.renderer(val, field, this.toJSON());
}
return val;
},
// ### getFieldValueUnrendered
//
// For the provided Field get the corresponding computed data value
// for this record.
//
// NB: if field is undefined a default '' value will be returned
getFieldValueUnrendered: function(field) {
if (!field) {
return '';
}
var val = this.get(field.id);
if (field.deriver) {
val = field.deriver(val, field, this);
}
return val;
},
// ### summary
//
// Get a simple html summary of this record in form of key/value list
summary: function(record) {
var self = this;
var html = '<div class="recline-record-summary">';
this.fields.each(function(field) {
if (field.id != 'id') {
html += '<div class="' + field.id + '"><strong>' + field.get('label') + '</strong>: ' + self.getFieldValue(field) + '</div>';
}
});
html += '</div>';
return html;
},
// Override Backbone save, fetch and destroy so they do nothing
// Instead, Dataset object that created this Record should take care of
// handling these changes (discovery will occur via event notifications)
// WARNING: these will not persist *unless* you call save on Dataset
fetch: function() {},
save: function() {},
destroy: function() { this.trigger('destroy', this); }
});
// ## A Backbone collection of Records
my.RecordList = Backbone.Collection.extend({
constructor: function RecordList() {
Backbone.Collection.prototype.constructor.apply(this, arguments);
},
model: my.Record
});
// ## <a id="field">A Field (aka Column) on a Dataset</a>
my.Field = Backbone.Model.extend({
constructor: function Field() {
Backbone.Model.prototype.constructor.apply(this, arguments);
},
// ### defaults - define default values
defaults: {
label: null,
type: 'string',
format: null,
is_derived: false
},
// ### initialize
//
// @param {Object} data: standard Backbone model attributes
//
// @param {Object} options: renderer and/or deriver functions.
initialize: function(data, options) {
// if a hash not passed in the first argument throw error
if ('0' in data) {
throw new Error('Looks like you did not pass a proper hash with id to Field constructor');
}
if (this.attributes.label === null) {
this.set({label: this.id});
}
if (this.attributes.type.toLowerCase() in this._typeMap) {
this.attributes.type = this._typeMap[this.attributes.type.toLowerCase()];
}
if (options) {
this.renderer = options.renderer;
this.deriver = options.deriver;
}
if (!this.renderer) {
this.renderer = this.defaultRenderers[this.get('type')];
}
this.facets = new my.FacetList();
},
_typeMap: {
'text': 'string',
'double': 'number',
'float': 'number',
'numeric': 'number',
'int': 'integer',
'datetime': 'date-time',
'bool': 'boolean',
'timestamp': 'date-time',
'json': 'object'
},
defaultRenderers: {
object: function(val, field, doc) {
return JSON.stringify(val);
},
geo_point: function(val, field, doc) {
return JSON.stringify(val);
},
'number': function(val, field, doc) {
var format = field.get('format');
if (format === 'percentage') {
return val + '%';
}
return val;
},
'string': function(val, field, doc) {
var format = field.get('format');
if (format === 'markdown') {
if (typeof Showdown !== 'undefined') {
var showdown = new Showdown.converter();
out = showdown.makeHtml(val);
return out;
} else {
return val;
}
} else if (format == 'plain') {
return val;
} else {
// as this is the default and default type is string may get things
// here that are not actually strings
if (val && typeof val === 'string') {
val = val.replace(/(https?:\/\/[^ ]+)/g, '<a href="$1">$1</a>');
}
return val;
}
}
}
});
my.FieldList = Backbone.Collection.extend({
constructor: function FieldList() {
Backbone.Collection.prototype.constructor.apply(this, arguments);
},
model: my.Field
});
// ## <a id="query">Query</a>
my.Query = Backbone.Model.extend({
constructor: function Query() {
Backbone.Model.prototype.constructor.apply(this, arguments);
},
defaults: function() {
return {
size: 100,
from: 0,
q: '',
facets: {},
filters: []
};
},
_filterTemplates: {
term: {
type: 'term',
// TODO do we need this attribute here?
field: '',
term: ''
},
range: {
type: 'range',
from: '',
to: ''
},
geo_distance: {
type: 'geo_distance',
distance: 10,
unit: 'km',
point: {
lon: 0,
lat: 0
}
}
},
// ### addFilter(filter)
//
// Add a new filter specified by the filter hash and append to the list of filters
//
// @param filter an object specifying the filter - see _filterTemplates for examples. If only type is provided will generate a filter by cloning _filterTemplates
addFilter: function(filter) {
// crude deep copy
var ourfilter = JSON.parse(JSON.stringify(filter));
// not fully specified so use template and over-write
if (_.keys(filter).length <= 3) {
ourfilter = _.defaults(ourfilter, this._filterTemplates[filter.type]);
}
var filters = this.get('filters');
filters.push(ourfilter);
this.trigger('change:filters:new-blank');
},
replaceFilter: function(filter) {
// delete filter on the same field, then add
var filters = this.get('filters');
var idx = -1;
_.each(this.get('filters'), function(f, key, list) {
if (filter.field == f.field) {
idx = key;
}
});
// trigger just one event (change:filters:new-blank) instead of one for remove and
// one for add
if (idx >= 0) {
filters.splice(idx, 1);
this.set({filters: filters});
}
this.addFilter(filter);
},
updateFilter: function(index, value) {
},
// ### removeFilter
//
// Remove a filter from filters at index filterIndex
removeFilter: function(filterIndex) {
var filters = this.get('filters');
filters.splice(filterIndex, 1);
this.set({filters: filters});
this.trigger('change');
},
// ### addFacet
//
// Add a Facet to this query
//
// See <http://www.elasticsearch.org/guide/reference/api/search/facets/>
addFacet: function(fieldId, size, silent) {
var facets = this.get('facets');
// Assume id and fieldId should be the same (TODO: this need not be true if we want to add two different type of facets on same field)
if (_.contains(_.keys(facets), fieldId)) {
return;
}
facets[fieldId] = {
terms: { field: fieldId }
};
if (!_.isUndefined(size)) {
facets[fieldId].terms.size = size;
}
this.set({facets: facets}, {silent: true});
if (!silent) {
this.trigger('facet:add', this);
}
},
addHistogramFacet: function(fieldId) {
var facets = this.get('facets');
facets[fieldId] = {
date_histogram: {
field: fieldId,
interval: 'day'
}
};
this.set({facets: facets}, {silent: true});
this.trigger('facet:add', this);
},
removeFacet: function(fieldId) {
var facets = this.get('facets');
// Assume id and fieldId should be the same (TODO: this need not be true if we want to add two different type of facets on same field)
if (!_.contains(_.keys(facets), fieldId)) {
return;
}
delete facets[fieldId];
this.set({facets: facets}, {silent: true});
this.trigger('facet:remove', this);
},
clearFacets: function() {
var facets = this.get('facets');
_.each(_.keys(facets), function(fieldId) {
delete facets[fieldId];
});
this.trigger('facet:remove', this);
},
// trigger a facet add; use this to trigger a single event after adding
// multiple facets
refreshFacets: function() {
this.trigger('facet:add', this);
}
});
// ## <a id="facet">A Facet (Result)</a>
my.Facet = Backbone.Model.extend({
constructor: function Facet() {
Backbone.Model.prototype.constructor.apply(this, arguments);
},
defaults: function() {
return {
_type: 'terms',
total: 0,
other: 0,
missing: 0,
terms: []
};
}
});
// ## A Collection/List of Facets
my.FacetList = Backbone.Collection.extend({
constructor: function FacetList() {
Backbone.Collection.prototype.constructor.apply(this, arguments);
},
model: my.Facet
});
// ## Object State
//
// Convenience Backbone model for storing (configuration) state of objects like Views.
my.ObjectState = Backbone.Model.extend({
});
// ## Backbone.sync
//
// Override Backbone.sync to hand off to sync function in relevant backend
// Backbone.sync = function(method, model, options) {
// return model.backend.sync(method, model, options);
// };
}(this.recline.Model));
this.recline = this.recline || {};
this.recline.Backend = this.recline.Backend || {};
this.recline.Backend.Memory = this.recline.Backend.Memory || {};
(function(my) {
"use strict";
my.__type__ = 'memory';
// private data - use either jQuery or Underscore Deferred depending on what is available
var Deferred = (typeof jQuery !== "undefined" && jQuery.Deferred) || _.Deferred;
// ## Data Wrapper
//
// Turn a simple array of JS objects into a mini data-store with
// functionality like querying, faceting, updating (by ID) and deleting (by
// ID).
//
// @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.
my.Store = function(records, fields) {
var self = this;
this.records = records;
// backwards compatability (in v0.5 records was named data)
this.data = this.records;
if (fields) {
this.fields = fields;
} else {
if (records) {
this.fields = _.map(records[0], function(value, key) {
return {id: key, type: 'string'};
});
}
}
this.update = function(doc) {
_.each(self.records, function(internalDoc, idx) {
if(doc.id === internalDoc.id) {
self.records[idx] = doc;
}
});
};
this.remove = function(doc) {
var newdocs = _.reject(self.records, function(internalDoc) {
return (doc.id === internalDoc.id);
});
this.records = newdocs;
};
this.save = function(changes, dataset) {
var self = this;
var dfd = new Deferred();
// TODO _.each(changes.creates) { ... }
_.each(changes.updates, function(record) {
self.update(record);
});
_.each(changes.deletes, function(record) {
self.remove(record);
});
dfd.resolve();
return dfd.promise();
},
this.query = function(queryObj) {
var dfd = new Deferred();
var numRows = queryObj.size || this.records.length;
var start = queryObj.from || 0;
var results = this.records;
results = this._applyFilters(results, queryObj);
results = this._applyFreeTextQuery(results, queryObj);
// TODO: this is not complete sorting!
// What's wrong is we sort on the *last* entry in the sort list if there are multiple sort criteria
_.each(queryObj.sort, function(sortObj) {
var fieldName = sortObj.field;
results = _.sortBy(results, function(doc) {
var _out = doc[fieldName];
return _out;
});
if (sortObj.order == 'desc') {
results.reverse();
}
});
var facets = this.computeFacets(results, queryObj);
var out = {
total: results.length,
hits: results.slice(start, start+numRows),
facets: facets
};
dfd.resolve(out);
return dfd.promise();
};
// in place filtering
this._applyFilters = function(results, queryObj) {
var filters = queryObj.filters;
// register filters
var filterFunctions = {
term : term,
terms : terms,
range : range,
geo_distance : geo_distance
};
var dataParsers = {
integer: function (e) { return parseFloat(e, 10); },
'float': function (e) { return parseFloat(e, 10); },
number: function (e) { return parseFloat(e, 10); },
string : function (e) { return e.toString(); },
date : function (e) { return moment(e).valueOf(); },
datetime : function (e) { return new Date(e).valueOf(); }
};
var keyedFields = {};
_.each(self.fields, function(field) {
keyedFields[field.id] = field;
});
function getDataParser(filter) {
var fieldType = keyedFields[filter.field].type || 'string';
return dataParsers[fieldType];
}
// filter records
return _.filter(results, function (record) {
var passes = _.map(filters, function (filter) {
return filterFunctions[filter.type](record, filter);
});
// return only these records that pass all filters
return _.all(passes, _.identity);
});
// filters definitions
function term(record, filter) {
var parse = getDataParser(filter);
var value = parse(record[filter.field]);
var term = parse(filter.term);
return (value === term);
}
function terms(record, filter) {
var parse = getDataParser(filter);
var value = parse(record[filter.field]);
var terms = parse(filter.terms).split(",");
return (_.indexOf(terms, value) >= 0);
}
function range(record, filter) {
var fromnull = (_.isUndefined(filter.from) || filter.from === null || filter.from === '');
var tonull = (_.isUndefined(filter.to) || filter.to === null || filter.to === '');
var parse = getDataParser(filter);
var value = parse(record[filter.field]);
var from = parse(fromnull ? '' : filter.from);
var to = parse(tonull ? '' : filter.to);
// if at least one end of range is set do not allow '' to get through
// note that for strings '' <= {any-character} e.g. '' <= 'a'
if ((!fromnull || !tonull) && value === '') {
return false;
}
return ((fromnull || value >= from) && (tonull || value <= to));
}
function geo_distance() {
// TODO code here
}
};
// we OR across fields but AND across terms in query string
this._applyFreeTextQuery = function(results, queryObj) {
if (queryObj.q) {
var terms = queryObj.q.split(' ');
var patterns=_.map(terms, function(term) {
return new RegExp(term.toLowerCase());
});
results = _.filter(results, function(rawdoc) {
var matches = true;
_.each(patterns, function(pattern) {
var foundmatch = false;
_.each(self.fields, function(field) {
var value = rawdoc[field.id];
if ((value !== null) && (value !== undefined)) {
value = value.toString();
} else {
// value can be null (apparently in some cases)
value = '';
}
// TODO regexes?
foundmatch = foundmatch || (pattern.test(value.toLowerCase()));
// TODO: early out (once we are true should break to spare unnecessary testing)
// if (foundmatch) return true;
});
matches = matches && foundmatch;
// TODO: early out (once false should break to spare unnecessary testing)
// if (!matches) return false;
});
return matches;
});
}
return results;
};
this.computeFacets = function(records, queryObj) {
var facetResults = {};
if (!queryObj.facets) {
return facetResults;
}
_.each(queryObj.facets, function(query, facetId) {
// TODO: remove dependency on recline.Model
facetResults[facetId] = new recline.Model.Facet({id: facetId}).toJSON();
facetResults[facetId].termsall = {};
});
// faceting
_.each(records, function(doc) {
_.each(queryObj.facets, function(query, facetId) {
var fieldId = query.terms.field;
var val = doc[fieldId];
var tmp = facetResults[facetId];
if (val) {
tmp.termsall[val] = tmp.termsall[val] ? tmp.termsall[val] + 1 : 1;
} else {
tmp.missing = tmp.missing + 1;
}
});
});
_.each(queryObj.facets, function(query, facetId) {
var tmp = facetResults[facetId];
var terms = _.map(tmp.termsall, function(count, term) {
return { term: term, count: count };
});
tmp.terms = _.sortBy(terms, function(item) {
// want descending order
return -item.count;
});
tmp.terms = tmp.terms.slice(0, 10);
});
return facetResults;
};
};
}(this.recline.Backend.Memory));

File diff suppressed because one or more lines are too long

4455
dist/recline.js vendored

File diff suppressed because it is too large Load Diff

3
dist/recline.min.js vendored

File diff suppressed because one or more lines are too long

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>
```

View File

@ -1,112 +0,0 @@
---
layout: container
title: Download
---
<div class="page-header">
<h1>
Download Recline
</h1>
</div>
<h2>Latest Code - Master</h2>
<p>The tutorials on this website will usually be based on the latest (master) codebase. It should also be very stable.</p>
<div class="row">
<div class="col-md-4">
<a href="dist/recline.js" class="btn btn-default">
<strong>recline.js (master) &raquo;</strong>
<br />
Single file containing all of Recline library
</a>
</div>
<div class="col-md-4">
<a href="dist/recline.dataset.js" class="btn btn-default">
<strong>recline.dataset.js (master) &raquo;</strong>
<br />
Single file with only the core data objects Dataset, Record etc without any Views or backends
</a>
</div>
<div class="col-md-4">
<a href="https://github.com/okfn/recline/zipball/master" class="btn btn-default">
<strong>Full package (master) &raquo;</strong>
<br />
Everything - library, source code, unit tests, vendor libraries and documentation
</a>
</div>
</div>
<h2>Most Recent Official Release &ndash; v0.5</h2>
<div class="row">
<div class="col-md-4">
<a href="https://raw.github.com/okfn/recline/v0.5/dist/recline.js" class="btn btn-default">
<strong>recline.js &raquo;</strong>
<br />
Single file containing all of Recline library
</a>
</div>
<div class="col-md-4">
<a href="https://raw.github.com/okfn/recline/v0.5/dist/recline.dataset.js" class="btn btn-default">
<strong>recline.dataset.js &raquo;</strong>
<br />
Single file with only the core data objects Dataset, Record etc without any Views or backends
</a>
</div>
<div class="col-md-4">
<a href="https://github.com/okfn/recline/zipball/v0.5" class="btn btn-default">
<strong>Full package (master) &raquo;</strong>
<br />
Everything - library, source code, unit tests, vendor libraries and documentation
</a>
</div>
</div>
<p style="margin-top: 20px;">After downloading recline you'll want to use it in your project -- see below or tutorials for details.</p>
### Changelog
[View Changelog on Github](https://github.com/okfn/recline#changelog)
### Dependencies
Recline has dependencies on some third-party libraries. Specifically, recline.dataset.js depends on:
* [Underscore](http://documentcloud.github.com/underscore/) &gt;= 1.0
* [Underscore Deferred](https://github.com/wookiehangover/underscore.deferred) v0.4.0
* [Backbone](http://backbonejs.org/) >= 0.5.1
Those backends which utilize jquery's ajax method depend on jQuery:
* [JQuery](http://jquery.com/) >= 1.6
All the views require, in addition to those needed for recline.dataset.js:
* [JQuery](http://jquery.com/) >= 1.6
* [Mustache.js](https://github.com/janl/mustache.js/) &gt;= 0.5.0-dev (required for all views)
Individual views have additional dependencies such as:
* [JQuery Flot](http://www.flotcharts.org/) >= 0.7 (required for for graph view)
* [Leaflet](http://leaflet.cloudmade.com/) >= 0.4.4 (required for map view)
* [Leaflet.markercluster](https://github.com/danzel/Leaflet.markercluster) as of 2012-09-12 (required for marker clustering)
* [Verite Timeline](https://github.com/VeriteCo/Timeline/) as of 2012-05-02 (required for the timeline view)
* [Bootstrap](http://twitter.github.com/bootstrap/) &gt;= v3 (default option for CSS and UI JS but you can use your own)
If you grab the full zipball for Recline this will include all of the relevant
dependencies in the vendor directory and you can also find them at in the
[github repo here](https://github.com/okfn/recline/tree/master/vendor).
### Example
Here is an example of the page setup for an app using every Recline component:
{% highlight html %}
<!-- bootstrap -->
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="vendor/bootstrap/3.2.0/css/bootstrap.css" />
{% include recline-deps.html %}
{% endhighlight %}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Some files were not shown because too many files have changed in this diff Show More