Added histograms to range slider facets.
git-svn-id: http://google-refine.googlecode.com/svn/trunk@25 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
00696a96fc
commit
ed5eae83af
@ -0,0 +1,88 @@
|
|||||||
|
package com.metaweb.gridlock.browsing.facets;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import com.metaweb.gridlock.expr.Evaluable;
|
||||||
|
import com.metaweb.gridlock.model.Cell;
|
||||||
|
import com.metaweb.gridlock.model.Project;
|
||||||
|
import com.metaweb.gridlock.model.Row;
|
||||||
|
|
||||||
|
public class NumericBinIndex {
|
||||||
|
public double min;
|
||||||
|
public double max;
|
||||||
|
public double step;
|
||||||
|
public int[] bins;
|
||||||
|
|
||||||
|
public NumericBinIndex(Project project, int cellIndex, Evaluable eval) {
|
||||||
|
Properties bindings = new Properties();
|
||||||
|
|
||||||
|
min = Double.POSITIVE_INFINITY;
|
||||||
|
max = Double.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
|
List<Double> allValues = new ArrayList<Double>();
|
||||||
|
for (int i = 0; i < project.rows.size(); i++) {
|
||||||
|
Row row = project.rows.get(i);
|
||||||
|
|
||||||
|
if (cellIndex < row.cells.size()) {
|
||||||
|
Cell cell = row.cells.get(cellIndex);
|
||||||
|
if (cell != null) {
|
||||||
|
bindings.put("project", project);
|
||||||
|
bindings.put("cell", cell);
|
||||||
|
bindings.put("value", cell.value);
|
||||||
|
|
||||||
|
Object value = eval.evaluate(bindings);
|
||||||
|
if (value != null) {
|
||||||
|
if (value.getClass().isArray()) {
|
||||||
|
Object[] a = (Object[]) value;
|
||||||
|
for (Object v : a) {
|
||||||
|
if (v instanceof Number) {
|
||||||
|
processValue(((Number) v).doubleValue(), allValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (value instanceof Number) {
|
||||||
|
processValue(((Number) value).doubleValue(), allValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min >= max) {
|
||||||
|
step = 0;
|
||||||
|
bins = new int[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double diff = max - min;
|
||||||
|
if (diff > 10) {
|
||||||
|
step = 1;
|
||||||
|
while (step * 100 < diff) {
|
||||||
|
step *= 10;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
step = 1;
|
||||||
|
while (step * 100 > diff) {
|
||||||
|
step /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
min = Math.floor(min / step) * step;
|
||||||
|
max = Math.ceil(max / step) * step;
|
||||||
|
|
||||||
|
int binCount = 1 + (int) Math.ceil((max - min) / step);
|
||||||
|
|
||||||
|
bins = new int[binCount];
|
||||||
|
for (double d : allValues) {
|
||||||
|
int bin = (int) Math.round((d - min) / step);
|
||||||
|
bins[bin]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void processValue(double v, List<Double> allValues) {
|
||||||
|
min = Math.min(min, v);
|
||||||
|
max = Math.max(max, v);
|
||||||
|
allValues.add(v);
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ import com.metaweb.gridlock.browsing.filters.ExpressionNumberComparisonRowFilter
|
|||||||
import com.metaweb.gridlock.browsing.filters.RowFilter;
|
import com.metaweb.gridlock.browsing.filters.RowFilter;
|
||||||
import com.metaweb.gridlock.expr.Evaluable;
|
import com.metaweb.gridlock.expr.Evaluable;
|
||||||
import com.metaweb.gridlock.expr.Parser;
|
import com.metaweb.gridlock.expr.Parser;
|
||||||
|
import com.metaweb.gridlock.model.Column;
|
||||||
import com.metaweb.gridlock.model.Project;
|
import com.metaweb.gridlock.model.Project;
|
||||||
|
|
||||||
public class RangeFacet implements Facet {
|
public class RangeFacet implements Facet {
|
||||||
@ -22,6 +23,11 @@ public class RangeFacet implements Facet {
|
|||||||
protected String _mode;
|
protected String _mode;
|
||||||
protected double _min;
|
protected double _min;
|
||||||
protected double _max;
|
protected double _max;
|
||||||
|
protected double _step;
|
||||||
|
protected int[] _bins;
|
||||||
|
|
||||||
|
protected double _from;
|
||||||
|
protected double _to;
|
||||||
|
|
||||||
public RangeFacet() {
|
public RangeFacet() {
|
||||||
}
|
}
|
||||||
@ -34,15 +40,24 @@ public class RangeFacet implements Facet {
|
|||||||
writer.key("name"); writer.value(_name);
|
writer.key("name"); writer.value(_name);
|
||||||
writer.key("expression"); writer.value(_expression);
|
writer.key("expression"); writer.value(_expression);
|
||||||
writer.key("cellIndex"); writer.value(_cellIndex);
|
writer.key("cellIndex"); writer.value(_cellIndex);
|
||||||
|
writer.key("min"); writer.value(_min);
|
||||||
|
writer.key("max"); writer.value(_max);
|
||||||
|
writer.key("step"); writer.value(_step);
|
||||||
|
|
||||||
|
writer.key("bins"); writer.array();
|
||||||
|
for (int b : _bins) {
|
||||||
|
writer.value(b);
|
||||||
|
}
|
||||||
|
writer.endArray();
|
||||||
|
|
||||||
writer.key("mode"); writer.value(_mode);
|
writer.key("mode"); writer.value(_mode);
|
||||||
if ("min".equals(_mode)) {
|
if ("min".equals(_mode)) {
|
||||||
writer.key("min"); writer.value(_min);
|
writer.key("from"); writer.value(_from);
|
||||||
} else if ("max".equals(_mode)) {
|
} else if ("max".equals(_mode)) {
|
||||||
writer.key("max"); writer.value(_max);
|
writer.key("to"); writer.value(_to);
|
||||||
} else {
|
} else {
|
||||||
writer.key("min"); writer.value(_min);
|
writer.key("from"); writer.value(_from);
|
||||||
writer.key("max"); writer.value(_max);
|
writer.key("to"); writer.value(_to);
|
||||||
}
|
}
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
}
|
}
|
||||||
@ -57,12 +72,12 @@ public class RangeFacet implements Facet {
|
|||||||
|
|
||||||
_mode = o.getString("mode");
|
_mode = o.getString("mode");
|
||||||
if ("min".equals(_mode)) {
|
if ("min".equals(_mode)) {
|
||||||
_min = o.getDouble("min");
|
_from = o.getDouble("from");
|
||||||
} else if ("max".equals(_mode)) {
|
} else if ("max".equals(_mode)) {
|
||||||
_max = o.getDouble("max");
|
_to = o.getDouble("to");
|
||||||
} else {
|
} else {
|
||||||
_min = o.getDouble("min");
|
_from = o.getDouble("from");
|
||||||
_max = o.getDouble("max");
|
_to = o.getDouble("to");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,19 +86,19 @@ public class RangeFacet implements Facet {
|
|||||||
if ("min".equals(_mode)) {
|
if ("min".equals(_mode)) {
|
||||||
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||||
protected boolean checkValue(double d) {
|
protected boolean checkValue(double d) {
|
||||||
return d >= _min;
|
return d >= _from;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else if ("max".equals(_mode)) {
|
} else if ("max".equals(_mode)) {
|
||||||
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||||
protected boolean checkValue(double d) {
|
protected boolean checkValue(double d) {
|
||||||
return d <= _max;
|
return d <= _to;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||||
protected boolean checkValue(double d) {
|
protected boolean checkValue(double d) {
|
||||||
return d >= _min && d <= _max;
|
return d >= _from && d <= _to;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -91,6 +106,18 @@ public class RangeFacet implements Facet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void computeChoices(Project project, FilteredRows filteredRows) {
|
public void computeChoices(Project project, FilteredRows filteredRows) {
|
||||||
// nothing to do
|
Column column = project.columnModel.getColumnByCellIndex(_cellIndex);
|
||||||
|
|
||||||
|
String key = "numeric-bin:" + _expression;
|
||||||
|
NumericBinIndex index = (NumericBinIndex) column.getPrecompute(key);
|
||||||
|
if (index == null) {
|
||||||
|
index = new NumericBinIndex(project, _cellIndex, _eval);
|
||||||
|
column.setPrecompute(key, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
_min = index.min;
|
||||||
|
_max = index.max;
|
||||||
|
_step = index.step;
|
||||||
|
_bins = index.bins;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public class ApproveNewReconcileCommand extends Command {
|
|||||||
}
|
}
|
||||||
}.init(cellIndex, cellChanges));
|
}.init(cellIndex, cellChanges));
|
||||||
|
|
||||||
MassCellChange massCellChange = new MassCellChange(cellChanges);
|
MassCellChange massCellChange = new MassCellChange(cellChanges, cellIndex);
|
||||||
HistoryEntry historyEntry = new HistoryEntry(
|
HistoryEntry historyEntry = new HistoryEntry(
|
||||||
project, "Approve new topics for " + columnName, massCellChange);
|
project, "Approve new topics for " + columnName, massCellChange);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public class ApproveReconcileCommand extends Command {
|
|||||||
}
|
}
|
||||||
}.init(cellIndex, cellChanges));
|
}.init(cellIndex, cellChanges));
|
||||||
|
|
||||||
MassCellChange massCellChange = new MassCellChange(cellChanges);
|
MassCellChange massCellChange = new MassCellChange(cellChanges, cellIndex);
|
||||||
HistoryEntry historyEntry = new HistoryEntry(
|
HistoryEntry historyEntry = new HistoryEntry(
|
||||||
project, "Approve best recon candidates for " + columnName, massCellChange);
|
project, "Approve best recon candidates for " + columnName, massCellChange);
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ public class DiscardReconcileCommand extends Command {
|
|||||||
}
|
}
|
||||||
}.init(cellIndex, cellChanges));
|
}.init(cellIndex, cellChanges));
|
||||||
|
|
||||||
MassCellChange massCellChange = new MassCellChange(cellChanges);
|
MassCellChange massCellChange = new MassCellChange(cellChanges, cellIndex);
|
||||||
HistoryEntry historyEntry = new HistoryEntry(
|
HistoryEntry historyEntry = new HistoryEntry(
|
||||||
project, "Discard recon results for " + columnName, massCellChange);
|
project, "Discard recon results for " + columnName, massCellChange);
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public class DoTextTransformCommand extends Command {
|
|||||||
}
|
}
|
||||||
}.init(cellIndex, bindings, cellChanges, eval));
|
}.init(cellIndex, bindings, cellChanges, eval));
|
||||||
|
|
||||||
MassCellChange massCellChange = new MassCellChange(cellChanges);
|
MassCellChange massCellChange = new MassCellChange(cellChanges, cellIndex);
|
||||||
HistoryEntry historyEntry = new HistoryEntry(
|
HistoryEntry historyEntry = new HistoryEntry(
|
||||||
project, "Text transform on " + columnName + ": " + expression, massCellChange);
|
project, "Text transform on " + columnName + ": " + expression, massCellChange);
|
||||||
|
|
||||||
|
@ -8,10 +8,12 @@ import com.metaweb.gridlock.model.Row;
|
|||||||
public class MassCellChange implements Change {
|
public class MassCellChange implements Change {
|
||||||
private static final long serialVersionUID = -933571199802688027L;
|
private static final long serialVersionUID = -933571199802688027L;
|
||||||
|
|
||||||
protected CellChange[] _cellChanges;
|
protected CellChange[] _cellChanges;
|
||||||
|
protected int _commonCellIndex;
|
||||||
|
|
||||||
public MassCellChange(List<CellChange> cellChanges) {
|
public MassCellChange(List<CellChange> cellChanges, int commonCellIndex) {
|
||||||
_cellChanges = new CellChange[cellChanges.size()];
|
_cellChanges = new CellChange[cellChanges.size()];
|
||||||
|
_commonCellIndex = commonCellIndex;
|
||||||
cellChanges.toArray(_cellChanges);
|
cellChanges.toArray(_cellChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +25,10 @@ public class MassCellChange implements Change {
|
|||||||
for (CellChange cellChange : _cellChanges) {
|
for (CellChange cellChange : _cellChanges) {
|
||||||
rows.get(cellChange.row).cells.set(cellChange.column, cellChange.newCell);
|
rows.get(cellChange.row).cells.set(cellChange.column, cellChange.newCell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_commonCellIndex >= 0) {
|
||||||
|
project.columnModel.getColumnByCellIndex(_commonCellIndex).clearPrecomputes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,10 @@ public class MassCellChange implements Change {
|
|||||||
for (CellChange cellChange : _cellChanges) {
|
for (CellChange cellChange : _cellChanges) {
|
||||||
rows.get(cellChange.row).cells.set(cellChange.column, cellChange.oldCell);
|
rows.get(cellChange.row).cells.set(cellChange.column, cellChange.oldCell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_commonCellIndex >= 0) {
|
||||||
|
project.columnModel.getColumnByCellIndex(_commonCellIndex).clearPrecomputes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.metaweb.gridlock.model;
|
package com.metaweb.gridlock.model;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@ -15,6 +17,8 @@ public class Column implements Serializable, Jsonizable {
|
|||||||
public String headerLabel;
|
public String headerLabel;
|
||||||
public Class valueType;
|
public Class valueType;
|
||||||
|
|
||||||
|
transient protected Map<String, Object> _precomputes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JSONWriter writer, Properties options)
|
public void write(JSONWriter writer, Properties options)
|
||||||
throws JSONException {
|
throws JSONException {
|
||||||
@ -25,4 +29,24 @@ public class Column implements Serializable, Jsonizable {
|
|||||||
writer.key("valueType"); writer.value(valueType == null ? null : valueType.getSimpleName());
|
writer.key("valueType"); writer.value(valueType == null ? null : valueType.getSimpleName());
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearPrecomputes() {
|
||||||
|
if (_precomputes != null) {
|
||||||
|
_precomputes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getPrecompute(String key) {
|
||||||
|
if (_precomputes != null) {
|
||||||
|
return _precomputes.get(key);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrecompute(String key, Object value) {
|
||||||
|
if (_precomputes == null) {
|
||||||
|
_precomputes = new HashMap<String, Object>();
|
||||||
|
}
|
||||||
|
_precomputes.put(key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class ReconProcess extends LongRunningProcess implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MassCellChange massCellChange = new MassCellChange(cellChanges);
|
MassCellChange massCellChange = new MassCellChange(cellChanges, _cellIndex);
|
||||||
HistoryEntry historyEntry = new HistoryEntry(_project, _description, massCellChange);
|
HistoryEntry historyEntry = new HistoryEntry(_project, _description, massCellChange);
|
||||||
|
|
||||||
_project.history.addEntry(historyEntry);
|
_project.history.addEntry(historyEntry);
|
||||||
|
@ -240,6 +240,7 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
|||||||
MenuSystem.createAndShowStandardMenu([
|
MenuSystem.createAndShowStandardMenu([
|
||||||
{
|
{
|
||||||
label: "Filter",
|
label: "Filter",
|
||||||
|
tooltip: "Filter rows by this column's cell content or characteristics",
|
||||||
submenu: [
|
submenu: [
|
||||||
{ "heading" : "On Cell Content" },
|
{ "heading" : "On Cell Content" },
|
||||||
{
|
{
|
||||||
@ -303,6 +304,9 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
|||||||
"name" : column.headerLabel + ": judgment",
|
"name" : column.headerLabel + ": judgment",
|
||||||
"cellIndex" : column.cellIndex,
|
"cellIndex" : column.cellIndex,
|
||||||
"expression" : "cell.recon.judgment"
|
"expression" : "cell.recon.judgment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scroll" : false
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -415,6 +419,7 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Collapse/Expand",
|
label: "Collapse/Expand",
|
||||||
|
tooltip: "Collapse/expand columns to make viewing the data more convenient",
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: "Collapse This Column",
|
label: "Collapse This Column",
|
||||||
@ -475,6 +480,7 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Reconcile",
|
label: "Reconcile",
|
||||||
|
tooltip: "Match this column's cells to topics on Freebase",
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: "Start Reconciling ...",
|
label: "Start Reconciling ...",
|
||||||
|
@ -12,14 +12,14 @@ function RangeFacet(div, config, options) {
|
|||||||
RangeFacet.prototype._setDefaults = function() {
|
RangeFacet.prototype._setDefaults = function() {
|
||||||
switch (this._config.mode) {
|
switch (this._config.mode) {
|
||||||
case "min":
|
case "min":
|
||||||
this._min = this._config.min;
|
this._from = this._config.min;
|
||||||
break;
|
break;
|
||||||
case "max":
|
case "max":
|
||||||
this._max = this._config.max;
|
this._to = this._config.max;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this._min = this._config.min;
|
this._from = this._config.min;
|
||||||
this._max = this._config.max;
|
this._to = this._config.max;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,18 +29,18 @@ RangeFacet.prototype.getJSON = function() {
|
|||||||
|
|
||||||
switch (this._config.mode) {
|
switch (this._config.mode) {
|
||||||
case "min":
|
case "min":
|
||||||
o.min = this._min;
|
o.from = this._from;
|
||||||
break;
|
break;
|
||||||
case "max":
|
case "max":
|
||||||
o.max = this._max;
|
o.to = this._to;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
o.min = this._min;
|
o.from = this._from;
|
||||||
if (this._max == this._config.max) {
|
if (this._to == this._config.max) {
|
||||||
// pretend to be open-ended
|
// pretend to be open-ended
|
||||||
o.mode = "min";
|
o.mode = "min";
|
||||||
} else {
|
} else {
|
||||||
o.max = this._max;
|
o.to = this._to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,12 +50,12 @@ RangeFacet.prototype.getJSON = function() {
|
|||||||
RangeFacet.prototype.hasSelection = function() {
|
RangeFacet.prototype.hasSelection = function() {
|
||||||
switch (this._config.mode) {
|
switch (this._config.mode) {
|
||||||
case "min":
|
case "min":
|
||||||
return this._min > this._config.min;
|
return this._from > this._config.min;
|
||||||
case "max":
|
case "max":
|
||||||
return this._max < this._config.max;
|
return this._to < this._config.max;
|
||||||
default:
|
default:
|
||||||
return this._min > this._config.min ||
|
return this._from > this._config.min ||
|
||||||
this._max < this._config.max;
|
this._to < this._config.max;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,21 +71,22 @@ RangeFacet.prototype._initializeUI = function() {
|
|||||||
}).prependTo(headerDiv);
|
}).prependTo(headerDiv);
|
||||||
|
|
||||||
var bodyDiv = $('<div></div>').addClass("facet-range-body").appendTo(container);
|
var bodyDiv = $('<div></div>').addClass("facet-range-body").appendTo(container);
|
||||||
|
|
||||||
|
this._histogramDiv = $('<div></div>').addClass("facet-range-histogram").appendTo(bodyDiv);
|
||||||
this._sliderDiv = $('<div></div>').addClass("facet-range-slider").appendTo(bodyDiv);
|
this._sliderDiv = $('<div></div>').addClass("facet-range-slider").appendTo(bodyDiv);
|
||||||
this._statusDiv = $('<div></div>').addClass("facet-range-status").appendTo(bodyDiv);
|
this._statusDiv = $('<div></div>').addClass("facet-range-status").appendTo(bodyDiv);
|
||||||
|
|
||||||
var onSlide = function(event, ui) {
|
var onSlide = function(event, ui) {
|
||||||
switch (self._config.mode) {
|
switch (self._config.mode) {
|
||||||
case "min":
|
case "min":
|
||||||
self._min = ui.value;
|
self._from = ui.value;
|
||||||
break;
|
break;
|
||||||
case "max":
|
case "max":
|
||||||
self._max = ui.value;
|
self._to = ui.value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
self._min = ui.values[0];
|
self._from = ui.values[0];
|
||||||
self._max = ui.values[1];
|
self._to = ui.values[1];
|
||||||
}
|
}
|
||||||
self._setRangeIndicators();
|
self._setRangeIndicators();
|
||||||
self._scheduleUpdate();
|
self._scheduleUpdate();
|
||||||
@ -104,15 +105,15 @@ RangeFacet.prototype._initializeUI = function() {
|
|||||||
switch (this._config.mode) {
|
switch (this._config.mode) {
|
||||||
case "min":
|
case "min":
|
||||||
sliderConfig.range = "max";
|
sliderConfig.range = "max";
|
||||||
sliderConfig.value = this._min;
|
sliderConfig.value = this._from;
|
||||||
break;
|
break;
|
||||||
case "max":
|
case "max":
|
||||||
sliderConfig.range = "min";
|
sliderConfig.range = "min";
|
||||||
sliderConfig.value = this._max;
|
sliderConfig.value = this._to;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sliderConfig.range = true;
|
sliderConfig.range = true;
|
||||||
sliderConfig.values = [ this._min, this._max ];
|
sliderConfig.values = [ this._from, this._to ];
|
||||||
}
|
}
|
||||||
this._sliderDiv.slider(sliderConfig);
|
this._sliderDiv.slider(sliderConfig);
|
||||||
this._setRangeIndicators();
|
this._setRangeIndicators();
|
||||||
@ -122,29 +123,36 @@ RangeFacet.prototype._setRangeIndicators = function() {
|
|||||||
var text;
|
var text;
|
||||||
switch (this._config.mode) {
|
switch (this._config.mode) {
|
||||||
case "min":
|
case "min":
|
||||||
text = "At least " + this._min;
|
text = "At least " + this._from;
|
||||||
break;
|
break;
|
||||||
case "max":
|
case "max":
|
||||||
text = "At most " + this._max;
|
text = "At most " + this._to;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
text = this._min + " to " + this._max;
|
text = this._from + " to " + this._to;
|
||||||
}
|
}
|
||||||
this._statusDiv.text(text);
|
this._statusDiv.text(text);
|
||||||
};
|
};
|
||||||
|
|
||||||
RangeFacet.prototype.updateState = function(data) {
|
RangeFacet.prototype.updateState = function(data) {
|
||||||
|
this._config.min = data.min;
|
||||||
|
this._config.max = data.max;
|
||||||
|
this._config.step = data.step;
|
||||||
|
this._bins = data.bins;
|
||||||
|
|
||||||
switch (this._config.mode) {
|
switch (this._config.mode) {
|
||||||
case "min":
|
case "min":
|
||||||
this._min = data.min;
|
this._from = Math.max(data.from, this._config.min);
|
||||||
break;
|
break;
|
||||||
case "max":
|
case "max":
|
||||||
this._max = data.max;
|
this._to = Math.min(data.to, this._config.max);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this._min = data.min;
|
this._from = Math.max(data.from, this._config.min);
|
||||||
if ("max" in data) {
|
if ("to" in data) {
|
||||||
this._max = data.max;
|
this._to = Math.min(data.to, this._config.max);
|
||||||
|
} else {
|
||||||
|
this._to = data.max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +160,30 @@ RangeFacet.prototype.updateState = function(data) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
RangeFacet.prototype.render = function() {
|
RangeFacet.prototype.render = function() {
|
||||||
|
this._sliderDiv.slider("option", "min", this._config.min);
|
||||||
|
this._sliderDiv.slider("option", "max", this._config.max);
|
||||||
|
this._sliderDiv.slider("option", "step", this._config.step);
|
||||||
|
|
||||||
|
var max = 0;
|
||||||
|
for (var i = 0; i < this._bins.length; i++) {
|
||||||
|
max = Math.max(max, this._bins[i]);
|
||||||
|
}
|
||||||
|
if (max == 0) {
|
||||||
|
this._histogramDiv.hide();
|
||||||
|
} else {
|
||||||
|
var a = [];
|
||||||
|
for (var i = 0; i < this._bins.length; i++) {
|
||||||
|
a.push(Math.round(100 * this._bins[i] / max));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._histogramDiv.empty().show();
|
||||||
|
$('<img />').attr("src",
|
||||||
|
"http://chart.apis.google.com/chart?cht=ls&chs=" +
|
||||||
|
this._histogramDiv[0].offsetWidth +
|
||||||
|
"x50&chd=t:" + a.join(",")
|
||||||
|
).appendTo(this._histogramDiv);
|
||||||
|
}
|
||||||
|
|
||||||
this._setRangeIndicators();
|
this._setRangeIndicators();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,12 +69,15 @@ a.facet-choice-link:hover {
|
|||||||
|
|
||||||
.facet-range-body {
|
.facet-range-body {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
padding: 5px;
|
padding: 15px;
|
||||||
|
}
|
||||||
|
.facet-range-histogram {
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
.facet-range-slider {
|
.facet-range-slider {
|
||||||
}
|
}
|
||||||
.facet-range-status {
|
.facet-range-status {
|
||||||
margin: 5px 0px;
|
margin-top: 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user