[#62,view/query][m]: start of faceting support with QueryFacetEditor.
* QueryFacetEditor in DataExplorer which displays facets but nothing yet happens. * NB: very much less than half way through (things look worse rather than better atm).
This commit is contained in:
parent
e3819d8f4e
commit
905659d86f
@ -60,6 +60,10 @@
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.recline-query-facet-editor {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* Notifications
|
||||
*********************************************************/
|
||||
|
||||
@ -81,19 +81,38 @@ function localDataset() {
|
||||
, name: '1-my-test-dataset'
|
||||
, id: datasetId
|
||||
},
|
||||
fields: [{id: 'x'}, {id: 'y'}, {id: 'z'}, {id: 'label'}],
|
||||
fields: [{id: 'x'}, {id: 'y'}, {id: 'z'}, {id: 'country'}, {id: 'label'}],
|
||||
documents: [
|
||||
{id: 0, x: 1, y: 2, z: 3, label: 'first'}
|
||||
, {id: 1, x: 2, y: 4, z: 6, label: 'second'}
|
||||
, {id: 2, x: 3, y: 6, z: 9, label: 'third'}
|
||||
, {id: 3, x: 4, y: 8, z: 12, label: 'fourth'}
|
||||
, {id: 4, x: 5, y: 10, z: 15, label: 'fifth'}
|
||||
, {id: 5, x: 6, y: 12, z: 18, label: 'sixth'}
|
||||
{id: 0, x: 1, y: 2, z: 3, country: 'DE', label: 'first'}
|
||||
, {id: 1, x: 2, y: 4, z: 6, country: 'UK', label: 'second'}
|
||||
, {id: 2, x: 3, y: 6, z: 9, country: 'US', label: 'third'}
|
||||
, {id: 3, x: 4, y: 8, z: 12, country: 'UK', label: 'fourth'}
|
||||
, {id: 4, x: 5, y: 10, z: 15, country: 'UK', label: 'fifth'}
|
||||
, {id: 5, x: 6, y: 12, z: 18, country: 'DE', label: 'sixth'}
|
||||
]
|
||||
};
|
||||
var backend = new recline.Backend.Memory();
|
||||
backend.addDataset(inData);
|
||||
var dataset = new recline.Model.Dataset({id: datasetId}, backend);
|
||||
// TODO: auto-compute in Memory backend ??
|
||||
dataset.facets = {
|
||||
'country': {
|
||||
terms: [
|
||||
{
|
||||
term: 'UK',
|
||||
count: 3
|
||||
},
|
||||
{
|
||||
term: 'DE',
|
||||
count: 2
|
||||
},
|
||||
{
|
||||
term: 'US',
|
||||
count: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
return dataset;
|
||||
}
|
||||
|
||||
|
||||
21
src/model.js
21
src/model.js
@ -23,6 +23,7 @@ my.Dataset = Backbone.Model.extend({
|
||||
}
|
||||
this.fields = new my.FieldList();
|
||||
this.currentDocuments = new my.DocumentList();
|
||||
this.facets = {};
|
||||
this.docCount = null;
|
||||
this.queryState = new my.Query();
|
||||
this.queryState.bind('change', this.query);
|
||||
@ -116,6 +117,26 @@ my.Query = Backbone.Model.extend({
|
||||
defaults: {
|
||||
size: 100
|
||||
, from: 0
|
||||
, facets: {}
|
||||
},
|
||||
initialize: function() {
|
||||
_.bindAll(this, 'addFacet');
|
||||
},
|
||||
|
||||
addFacet: function(fieldId) {
|
||||
// TODO: utilize field info to determine facet type ??
|
||||
var facets = this.get('facets');
|
||||
if (fieldId in facets) {
|
||||
return;
|
||||
}
|
||||
facets[fieldId] = {
|
||||
terms: {
|
||||
field: fieldId
|
||||
}
|
||||
}
|
||||
this.set({facets: facets});
|
||||
// trigger change event (does not seem to be triggered o/w)
|
||||
// this.change();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
67
src/view.js
67
src/view.js
@ -168,6 +168,12 @@ my.DataExplorer = Backbone.View.extend({
|
||||
model: this.model.queryState
|
||||
});
|
||||
this.el.find('.header').append(queryEditor.el);
|
||||
var queryFacetEditor = new my.QueryFacetEditor({
|
||||
model: this.model.queryState
|
||||
},
|
||||
this.model
|
||||
);
|
||||
this.el.find('.header').append(queryFacetEditor.el);
|
||||
},
|
||||
|
||||
setupRouting: function() {
|
||||
@ -275,6 +281,67 @@ my.QueryEditor = Backbone.View.extend({
|
||||
}
|
||||
});
|
||||
|
||||
my.QueryFacetEditor = Backbone.View.extend({
|
||||
className: 'recline-query-facet-editor',
|
||||
template: ' \
|
||||
<a class="btn dropdown-toggle" data-toggle="drop-down">Add filter on</a> \
|
||||
<ul class="dropdown-menu js-faceton"> \
|
||||
{{#fields}} \
|
||||
<li name="{{id}}">{{label}}</li> \
|
||||
{{/fields}} \
|
||||
</ul> \
|
||||
<div class="facets"> \
|
||||
{{#facets}} \
|
||||
<a class="btn js-facet-show-toggle" data-facet="{{label}}"><i class="icon-plus"></i> {{label}}</a> \
|
||||
<ul class="facet-items" data-facet="{{label}}" style="display: none;"> \
|
||||
{{#terms}} \
|
||||
<li>{{term}} ({{count}}) <input type="checkbox" class="facet-choice" data-facet="{{label}}" value="{{term}}" /></li> \
|
||||
{{/terms}} \
|
||||
</ul> \
|
||||
{{/facets}} \
|
||||
</div> \
|
||||
',
|
||||
|
||||
events: {
|
||||
'change .js-faceton': 'onAddFilter',
|
||||
'click .js-facet-show-toggle': 'onFacetShowToggle'
|
||||
},
|
||||
initialize: function(model, dataset) {
|
||||
_.bindAll(this, 'render');
|
||||
this.el = $(this.el);
|
||||
this.model.bind('change', this.render);
|
||||
this.dataset = dataset;
|
||||
this.dataset.fields.bind('add', this.render);
|
||||
this.dataset.fields.bind('reset', this.render);
|
||||
this.dataset.fields.bind('remove', this.render);
|
||||
this.render();
|
||||
},
|
||||
render: function() {
|
||||
var tmplData = {
|
||||
query: this.model.toJSON(),
|
||||
fields: this.dataset.fields.toJSON()
|
||||
};
|
||||
tmplData.facets = _.map(this.dataset.facets, function(data, key) {
|
||||
var out = _.extend({label: key}, data);
|
||||
return out;
|
||||
})
|
||||
var templated = $.mustache(this.template, tmplData);
|
||||
this.el.html(templated);
|
||||
},
|
||||
onAddFilter: function(e) {
|
||||
var fieldId = $(e.target).find('option:selected').attr('name');
|
||||
this.model.addFacet(fieldId);
|
||||
// calculate facets for that field (if not already there??)
|
||||
// re-render will happen automatically as dataset will have updated
|
||||
},
|
||||
onFacetShowToggle: function(e) {
|
||||
e.preventDefault();
|
||||
var $a = $(e.target);
|
||||
var facetId = $a.attr('data-facet');
|
||||
var $ul = this.el.find('.facet-items[data-facet="' + facetId + '"]');
|
||||
$ul.toggle();
|
||||
}
|
||||
});
|
||||
|
||||
/* ========================================================== */
|
||||
// ## Miscellaneous Utilities
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user