Made data table view render "rows" or "records" depending on the mode.

Got rid of "show dependent rows" and replaced it with 2 radio buttons for the 2 modes: row-based vs. record-based.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@831 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-05-20 05:49:13 +00:00
parent ef2079d0d8
commit e1feec436a
8 changed files with 86 additions and 78 deletions

View File

@ -29,6 +29,7 @@ public class GetModelsCommand extends Command {
writer.object(); writer.object();
writer.key("columnModel"); project.columnModel.write(writer, options); writer.key("columnModel"); project.columnModel.write(writer, options);
writer.key("recordModel"); project.recordModel.write(writer, options);
writer.key("protograph"); writer.key("protograph");
if (project.protograph == null) { if (project.protograph == null) {
writer.value(null); writer.value(null);

View File

@ -46,47 +46,7 @@ public class GetRowsCommand extends Command {
JSONWriter writer = new JSONWriter(response.getWriter()); JSONWriter writer = new JSONWriter(response.getWriter());
writer.object(); writer.object();
RowAccumulator acc = new RowAccumulator(start, limit) { RowWritingVisitor acc = new RowWritingVisitor(start, limit, writer, options);
JSONWriter writer;
Properties options;
public RowAccumulator init(JSONWriter writer, Properties options) {
this.writer = writer;
this.options = options;
return this;
}
@Override
public boolean internalVisit(Project project, int rowIndex, Row row) {
try {
options.put("rowIndex", rowIndex);
row.write(writer, options);
} catch (JSONException e) {
}
return false;
}
@Override
protected boolean internalVisit(Project project, Record record) {
options.put("recordIndex", record.recordIndex);
for (int r = record.fromRowIndex; r < record.toRowIndex; r++) {
try {
Row row = project.rows.get(r);
options.put("rowIndex", r);
row.write(writer, options);
} catch (JSONException e) {
}
options.remove("recordIndex");
}
return false;
}
}.init(writer, options);
if (engine.getMode() == Mode.RowBased) { if (engine.getMode() == Mode.RowBased) {
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
@ -119,44 +79,66 @@ public class GetRowsCommand extends Command {
} }
} }
static protected class RowAccumulator implements RowVisitor, RecordVisitor { static protected class RowWritingVisitor implements RowVisitor, RecordVisitor {
final public int start; final int start;
final public int limit; final int limit;
final JSONWriter writer;
final Properties options;
public int total; public int total;
public RowAccumulator(int start, int limit) { public RowWritingVisitor(int start, int limit, JSONWriter writer, Properties options) {
this.start = start; this.start = start;
this.limit = limit; this.limit = limit;
this.writer = writer;
this.options = options;
} }
public boolean visit(Project project, int rowIndex, Row row) { public boolean visit(Project project, int rowIndex, Row row) {
boolean r = false;
if (total >= start && total < start + limit) { if (total >= start && total < start + limit) {
r = internalVisit(project, rowIndex, row); internalVisit(project, rowIndex, row);
} }
total++; total++;
return r;
return false;
} }
@Override @Override
public boolean visit(Project project, Record record) { public boolean visit(Project project, Record record) {
boolean r = false;
if (total >= start && total < start + limit) { if (total >= start && total < start + limit) {
r = internalVisit(project, record); internalVisit(project, record);
} }
total++; total++;
return r;
return false;
} }
protected boolean internalVisit(Project project, int rowIndex, Row row) { public boolean internalVisit(Project project, int rowIndex, Row row) {
try {
options.put("rowIndex", rowIndex);
row.write(writer, options);
} catch (JSONException e) {
}
return false; return false;
} }
protected boolean internalVisit(Project project, Record record) { protected boolean internalVisit(Project project, Record record) {
return false; options.put("recordIndex", record.recordIndex);
for (int r = record.fromRowIndex; r < record.toRowIndex; r++) {
try {
Row row = project.rows.get(r);
options.put("rowIndex", r);
row.write(writer, options);
} catch (JSONException e) {
}
options.remove("recordIndex");
}
return false;
} }
} }
} }

View File

@ -28,7 +28,6 @@ public class ColumnModel implements Jsonizable {
transient protected Map<Integer, Column> _cellIndexToColumn; transient protected Map<Integer, Column> _cellIndexToColumn;
transient protected List<ColumnGroup> _rootColumnGroups; transient protected List<ColumnGroup> _rootColumnGroups;
transient protected List<String> _columnNames; transient protected List<String> _columnNames;
transient boolean _hasDependentRows;
public ColumnModel() { public ColumnModel() {
internalInitialize(); internalInitialize();
@ -129,8 +128,6 @@ public class ColumnModel implements Jsonizable {
writer.object(); writer.object();
writer.key("hasDependentRows"); writer.value(_hasDependentRows);
writer.key("columns"); writer.key("columns");
writer.array(); writer.array();
for (Column column : columns) { for (Column column : columns) {

View File

@ -4,10 +4,15 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
import com.metaweb.gridworks.expr.ExpressionUtils; import com.metaweb.gridworks.expr.ExpressionUtils;
public class RecordModel { public class RecordModel implements Jsonizable {
final static public class CellDependency { final static public class CellDependency {
final public int rowIndex; final public int rowIndex;
final public int cellIndex; final public int cellIndex;
@ -52,6 +57,14 @@ public class RecordModel {
return null; return null;
} }
synchronized public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("hasRecords"); writer.value(_records.size() < _rowDependencies.size());
writer.endObject();
}
static protected class KeyedGroup { static protected class KeyedGroup {
int[] cellIndices; int[] cellIndices;
int keyCellIndex; int keyCellIndex;
@ -110,8 +123,6 @@ public class RecordModel {
} }
} }
Collections.sort(rowDependency.contextRows); Collections.sort(rowDependency.contextRows);
columnModel._hasDependentRows = true;
} else { } else {
rowDependency.recordIndex = recordIndex++; rowDependency.recordIndex = recordIndex++;
} }

View File

@ -141,11 +141,10 @@ Gridworks.reinitializeProjectData = function(f) {
}, },
"/command/get-models?" + $.param({ project: theProject.id }), null, "/command/get-models?" + $.param({ project: theProject.id }), null,
function(data) { function(data) {
theProject.columnModel = data.columnModel; for (var n in data) {
theProject.protograph = data.protograph; if (data.hasOwnProperty(n)) {
theProject[n] = data[n];
for (var i = 0; i < theProject.columnModel.columns.length; i++) { }
theProject.columnModel.columns[i].collapsed = false;
} }
}, },
f f

View File

@ -60,6 +60,13 @@ BrowsingEngine.prototype._initializeUI = function() {
'<p>by choosing a facet or filter method from the menus at the top of each column.</p>' + '<p>by choosing a facet or filter method from the menus at the top of each column.</p>' +
'<p>Not sure how to get started? <a href="http://vimeo.com/groups/gridworks/videos" target="_blank">Watch these screencasts</a>.</p>' + '<p>Not sure how to get started? <a href="http://vimeo.com/groups/gridworks/videos" target="_blank">Watch these screencasts</a>.</p>' +
'</div>' + '</div>' +
'<div class="browsing-panel-modes">' +
'Browse by ' +
'<span bind="modeSelectors">' +
'<input type="radio" id="browsing-panel-mode-row-based" name="browsing-panel-mode" value="row-based" /><label for="browsing-panel-mode-row-based">rows</label>' +
'<input type="radio" id="browsing-panel-mode-record-based" name="browsing-panel-mode" value="record-based" /><label for="browsing-panel-mode-record-based">records</label>' +
'</span>' +
'</div>' +
'<div class="browsing-panel-header" bind="header">' + '<div class="browsing-panel-header" bind="header">' +
'<div class="browsing-panel-indicator" bind="indicator">' + '<div class="browsing-panel-indicator" bind="indicator">' +
'<img src="images/small-spinner.gif" /> refreshing facets ...' + '<img src="images/small-spinner.gif" /> refreshing facets ...' +
@ -76,9 +83,6 @@ BrowsingEngine.prototype._initializeUI = function() {
'<a href="javascript:{}" bind="removeLink" class="action" title="Remove all facets">Remove&nbsp;All</a>' + '<a href="javascript:{}" bind="removeLink" class="action" title="Remove all facets">Remove&nbsp;All</a>' +
'</td>' + '</td>' +
'</tr>' + '</tr>' +
'<tr bind="dependentRowControls">' +
'<td colspan="3"><input type="checkbox" class="inline" bind="includeDependentRowsCheck" /> show dependent rows</td>' +
'</tr>' +
'</table></div></div>' + '</table></div></div>' +
'</div>' + '</div>' +
'<ul bind="facets" class="facets-container"></ul>' '<ul bind="facets" class="facets-container"></ul>'
@ -92,7 +96,11 @@ BrowsingEngine.prototype._initializeUI = function() {
}); });
this._elmts.facets.disableSelection(); this._elmts.facets.disableSelection();
this._elmts.includeDependentRowsCheck.change(function() { $("#browsing-panel-mode-" +
(theProject.recordModel.hasRecords ? 'record-based' : 'row-based')).attr("checked", "checked");
this._elmts.modeSelectors.buttonset();
this._elmts.modeSelectors.find("input").change(function() {
Gridworks.update({ engineChanged: true }); Gridworks.update({ engineChanged: true });
}); });
@ -119,7 +127,7 @@ BrowsingEngine.prototype._updateFacetOrder = function() {
BrowsingEngine.prototype.getJSON = function(keepUnrestrictedFacets, except) { BrowsingEngine.prototype.getJSON = function(keepUnrestrictedFacets, except) {
var a = { var a = {
facets: [], facets: [],
includeDependent: this._elmts.includeDependentRowsCheck[0].checked mode: this._elmts.modeSelectors.find("input:checked")[0].value
}; };
for (var i = 0; i < this._facets.length; i++) { for (var i = 0; i < this._facets.length; i++) {
var facet = this._facets[i]; var facet = this._facets[i];
@ -212,12 +220,6 @@ BrowsingEngine.prototype.update = function(onDone) {
self._elmts.header.show(); self._elmts.header.show();
self._elmts.controls.css("visibility", "visible"); self._elmts.controls.css("visibility", "visible");
if (theProject.columnModel.hasDependentRows) {
self._elmts.dependentRowControls.show();
} else {
self._elmts.dependentRowControls.hide();
}
self.resize(); self.resize();
} else { } else {
self._elmts.help.show(); self._elmts.help.show();

View File

@ -105,7 +105,10 @@ DataTableView.prototype._renderPagingControls = function(pageSizeControls, pagin
for (var i = 0; i < sizes.length; i++) { for (var i = 0; i < sizes.length; i++) {
renderPageSize(i); renderPageSize(i);
} }
$('<span> rows</span>').appendTo(pageSizeControls);
$('<span>')
.text(theProject.rowModel.mode == "record-based" ? ' records' : ' rows')
.appendTo(pageSizeControls);
}; };
DataTableView.prototype._renderDataTable = function(table) { DataTableView.prototype._renderDataTable = function(table) {

View File

@ -1,3 +1,15 @@
.browsing-panel-modes {
margin: 1em 0;
text-align: center;
}
.browsing-panel-modes .ui-button .ui-button-text {
line-height: 1.0;
text-decoration: line-through;
}
.browsing-panel-modes .ui-button.ui-state-active .ui-button-text {
text-decoration: none;
}
.browsing-panel-header { .browsing-panel-header {
position: relative; position: relative;
display: none; display: none;
@ -20,6 +32,7 @@
.browsing-panel-indicator img { .browsing-panel-indicator img {
vertical-align: text-top; vertical-align: text-top;
} }
.browsing-panel-controls { .browsing-panel-controls {
visibility: hidden; visibility: hidden;
} }