diff --git a/docs/src/backend.ckan.html b/docs/src/backend.ckan.html index 373c3422..2130baa2 100644 --- a/docs/src/backend.ckan.html +++ b/docs/src/backend.ckan.html @@ -8,11 +8,34 @@
General notes
+We need 2 things to make most requests:
+ +There are 2 ways to specify this information.
+ +EITHER (checked in order):
+ my.__type__ = 'ckan';Default CKAN API endpoint used for requests (you can change this but it will affect every request!)
my.API_ENDPOINT = 'http://datahub.io/api'; my.fetch = function(dataset) {
- var wrapper = my.DataStore();
+OR:
+ +Set the url attribute of the dataset to point to the Resource on the CKAN instance. The endpoint and id will then be automatically computed.
my.__type__ = 'ckan';Default CKAN API endpoint used for requests (you can change this but it will affect every request!)
+ +DEPRECATION: this will be removed in v0.7. Please set endpoint attribute on dataset instead
my.API_ENDPOINT = 'http://datahub.io/api'; my.fetch = function(dataset) {
+ if (dataset.endpoint) {
+ var wrapper = my.DataStore(dataset.endpoint);
+ } else {
+ var out = my._parseCkanResourceUrl(dataset.url);
+ dataset.id = out.resource_id;
+ var wrapper = my.DataStore(out.endpoint);
+ }
var dfd = $.Deferred();
var jqxhr = wrapper.search({resource_id: dataset.id, limit: 0});
jqxhr.done(function(results) {map ckan types to our usual types ...
var fields = _.map(results.result.fields, function(field) {
@@ -43,8 +66,14 @@
}
my.query = function(queryObj, dataset) {
+ if (dataset.endpoint) {
+ var wrapper = my.DataStore(dataset.endpoint);
+ } else {
+ var out = my._parseCkanResourceUrl(dataset.url);
+ dataset.id = out.resource_id;
+ var wrapper = my.DataStore(out.endpoint);
+ }
var actualQuery = my._normalizeQuery(queryObj, dataset);
- var wrapper = my.DataStore();
var dfd = $.Deferred();
var jqxhr = wrapper.search(actualQuery);
jqxhr.done(function(results) {
@@ -74,15 +103,21 @@
}
return that;
- }
+ };Parse a normal CKAN resource URL and return API endpoint etc
+ +Normal URL is something like http://demo.ckan.org/dataset/some-dataset/resource/eb23e809-ccbb-4ad1-820a-19586fc4bebd
my._parseCkanResourceUrl = function(url) {
+ parts = url.split('/');
+ var len = parts.length;
+ return {
+ resource_id: parts[len-1],
+ endpoint: parts.slice(0,[len-4]).join('/') + '/api'
+ }
+ };
var CKAN_TYPES_MAP = {
'int4': 'integer',
'int8': 'integer',
- 'float8': 'float',
- 'text': 'string',
- 'json': 'object',
- 'timestamp': 'date'
+ 'float8': 'float'
};
}(jQuery, this.recline.Backend.Ckan));
diff --git a/docs/src/backend.csv.html b/docs/src/backend.csv.html
index 4de7225a..34118c88 100644
--- a/docs/src/backend.csv.html
+++ b/docs/src/backend.csv.html
@@ -97,7 +97,7 @@ http://www.uselesscode.org/javascript/csv/ If we are at a EOF or EOR
if (inQuote === false && (cur === delimiter || cur === "\n")) {
- field = processField(field);Add the current field to the current row
row.push(field);If this is EOR append row to output and flush row
if (cur === "\n") {
+ field = processField(field);Add the current field to the current row
row.push(field);If this is EOR append row to output and flush row
if (cur === "\n") {
out.push(row);
row = [];
}Flush the field buffer
field = '';
diff --git a/docs/src/backend.memory.html b/docs/src/backend.memory.html
index 6ab3e14f..3cdd26fc 100644
--- a/docs/src/backend.memory.html
+++ b/docs/src/backend.memory.html
@@ -112,16 +112,20 @@ What's wrong is we sort on the last entry in the sort list if there are
}
function range(record, filter) {
+ var startnull = (filter.start == null || filter.start === '');
+ var stopnull = (filter.stop == null || filter.stop === '');
var parse = getDataParser(filter);
var value = parse(record[filter.field]);
var start = parse(filter.start);
- var stop = parse(filter.stop);
-
- return (value >= start && value <= stop);
+ var stop = parse(filter.stop);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 ((!startnull || !stopnull) && value === '') {
+ return false;
+ }
+ return ((startnull || value >= start) && (stopnull || value <= stop));
}
- function geo_distance() {TODO code here
}
- };we OR across fields but AND across terms in query string
this._applyFreeTextQuery = function(results, queryObj) {
+ 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) {
@@ -135,10 +139,10 @@ What's wrong is we sort on the last entry in the sort list if there are
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) + } 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) + matches = matches && foundmatch;
TODO: early out (once false should break to spare unnecessary testing) if (!matches) return false;
});
return matches;
});
@@ -151,9 +155,9 @@ if (!matches) return false; TODO: remove dependency on recline.Model
facetResults[facetId] = new recline.Model.Facet({id: facetId}).toJSON();
+ _.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) {
+ });faceting
_.each(records, function(doc) {
_.each(queryObj.facets, function(query, facetId) {
var fieldId = query.terms.field;
var val = doc[fieldId];
@@ -170,7 +174,7 @@ if (!matches) return false; want descending order
return -item.count;
+ tmp.terms = _.sortBy(terms, function(item) {want descending order
return -item.count;
});
tmp.terms = tmp.terms.slice(0, 10);
});
@@ -178,7 +182,7 @@ if (!matches) return false; TODO: very inefficient -- could probably just walk the documents and updates in tandem and update
_.each(toUpdate.updates, function(record, idx) {
+ var toUpdate = recline.Data.Transform.mapDocs(this.data, editFunc);TODO: very inefficient -- could probably just walk the documents and updates in tandem and update
_.each(toUpdate.updates, function(record, idx) {
self.data[idx] = record;
});
return this.save(toUpdate);
diff --git a/docs/src/docco.css b/docs/src/docco.css
index 04cc7ecb..5aa0a8d7 100644
--- a/docs/src/docco.css
+++ b/docs/src/docco.css
@@ -21,12 +21,6 @@ h1, h2, h3, h4, h5, h6 {
h1 {
margin-top: 40px;
}
-hr {
- border: 0 none;
- border-top: 1px solid #e5e5ee;
- height: 1px;
- margin: 20px 0;
-}
#container {
position: relative;
}
@@ -121,7 +115,7 @@ table td {
}
pre, tt, code {
font-size: 12px; line-height: 18px;
- font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
+ font-family: Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0;
}
diff --git a/docs/src/model.html b/docs/src/model.html
index 5ac6ed8c..a177a460 100644
--- a/docs/src/model.html
+++ b/docs/src/model.html
@@ -297,6 +297,9 @@ WARNING: these will not persist unless you call save on Dataset
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;
@@ -306,6 +309,17 @@ WARNING: these will not persist unless you call save on Dataset
}
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);
@@ -313,7 +327,7 @@ WARNING: these will not persist unless you call save on Dataset
geo_point: function(val, field, doc) {
return JSON.stringify(val);
},
- 'float': function(val, field, doc) {
+ 'number': function(val, field, doc) {
var format = field.get('format');
if (format === 'percentage') {
return val + '%';
diff --git a/docs/src/view.graph.html b/docs/src/view.graph.html
index 96d55abc..fd87f132 100644
--- a/docs/src/view.graph.html
+++ b/docs/src/view.graph.html
@@ -123,7 +123,8 @@ generate the element itself (you can then append view.el to the DOM.
};
var getFormattedX = function (x) {
- var xfield = self.model.fields.get(self.state.attributes.group);time series
var isDateTime = xfield.get('type') === 'date';
+ var xfield = self.model.fields.get(self.state.attributes.group);time series
var xtype = xfield.get('type');
+ var isDateTime = (xtype === 'date' || xtype === 'date-time' || xtype === 'time');
if (self.model.records.models[parseInt(x)]) {
x = self.model.records.models[parseInt(x)].get(self.state.attributes.group);
@@ -232,7 +233,8 @@ generate the element itself (you can then append view.el to the DOM.
var points = [];
_.each(self.model.records.models, function(doc, index) {
var xfield = self.model.fields.get(self.state.attributes.group);
- var x = doc.getFieldValue(xfield);time series
var isDateTime = xfield.get('type') === 'date';
+ var x = doc.getFieldValue(xfield);time series
var xtype = xfield.get('type');
+ var isDateTime = (xtype === 'date' || xtype === 'date-time' || xtype === 'time');
if (isDateTime) {datetime
if (self.state.attributes.graphType != 'bars' && self.state.attributes.graphType != 'columns') {not bar or column
x = new Date(x).getTime();
} else {bar or column
x = index;
diff --git a/docs/src/view.slickgrid.html b/docs/src/view.slickgrid.html
index 0745f9c4..481b5571 100644
--- a/docs/src/view.slickgrid.html
+++ b/docs/src/view.slickgrid.html
@@ -72,7 +72,7 @@ row = row index, cell = cell index, value = value, columnDef = column definition
columns.push(column);
});Restrict the visible columns
var visibleColumns = columns.filter(function(column) {
return _.indexOf(self.state.get('hiddenColumns'), column.id) == -1;
- });Order them if there is ordering info on the state
if (this.state.get('columnsOrder')){
+ });Order them if there is ordering info on the state
if (this.state.get('columnsOrder') && this.state.get('columnsOrder').length > 0) {
visibleColumns = visibleColumns.sort(function(a,b){
return _.indexOf(self.state.get('columnsOrder'),a.id) > _.indexOf(self.state.get('columnsOrder'),b.id) ? 1 : -1;
});
diff --git a/docs/src/widget.filtereditor.html b/docs/src/widget.filtereditor.html
index 08a94a2b..128e953e 100644
--- a/docs/src/widget.filtereditor.html
+++ b/docs/src/widget.filtereditor.html
@@ -13,18 +13,18 @@
<a href="#" class="js-add-filter">Add filter</a> \
<form class="form-stacked js-add" style="display: none;"> \
<fieldset> \
- <label>Filter type</label> \
- <select class="filterType"> \
- <option value="term">Term (text)</option> \
- <option value="range">Range</option> \
- <option value="geo_distance">Geo distance</option> \
- </select> \
<label>Field</label> \
<select class="fields"> \
{{#fields}} \
<option value="{{id}}">{{label}}</option> \
{{/fields}} \
</select> \
+ <label>Filter type</label> \
+ <select class="filterType"> \
+ <option value="term">Value</option> \
+ <option value="range">Range</option> \
+ <option value="geo_distance">Geo distance</option> \
+ </select> \
<button type="submit" class="btn">Add</button> \
</fieldset> \
</form> \
@@ -44,7 +44,7 @@
<fieldset> \
<legend> \
{{field}} <small>{{type}}</small> \
- <a class="js-remove-filter" href="#" title="Remove this filter">×</a> \
+ <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">×</a> \
</legend> \
<input type="text" value="{{term}}" name="term" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
</fieldset> \
@@ -55,7 +55,7 @@
<fieldset> \
<legend> \
{{field}} <small>{{type}}</small> \
- <a class="js-remove-filter" href="#" title="Remove this filter">×</a> \
+ <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">×</a> \
</legend> \
<label class="control-label" for="">From</label> \
<input type="text" value="{{start}}" name="start" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
@@ -69,7 +69,7 @@
<fieldset> \
<legend> \
{{field}} <small>{{type}}</small> \
- <a class="js-remove-filter" href="#" title="Remove this filter">×</a> \
+ <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">×</a> \
</legend> \
<label class="control-label" for="">Longitude</label> \
<input type="text" value="{{point.lon}}" name="lon" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
@@ -125,7 +125,7 @@
onRemoveFilter: function(e) {
e.preventDefault();
var $target = $(e.target);
- var filterId = $target.closest('.filter').attr('data-filter-id');
+ var filterId = $target.attr('data-filter-id');
this.model.queryState.removeFilter(filterId);
},
onTermFiltersUpdate: function(e) {