Added command Transpose Cells in Rows into Columns (Issue 82).

git-svn-id: http://google-refine.googlecode.com/svn/trunk@1147 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-08-08 06:30:30 +00:00
parent 7d4125654e
commit 8f071ede31
5 changed files with 196 additions and 0 deletions

View File

@ -74,6 +74,7 @@ public class GridworksServlet extends Butterfly {
{"fill-down", "com.google.gridworks.commands.cell.FillDownCommand"}, {"fill-down", "com.google.gridworks.commands.cell.FillDownCommand"},
{"blank-down", "com.google.gridworks.commands.cell.BlankDownCommand"}, {"blank-down", "com.google.gridworks.commands.cell.BlankDownCommand"},
{"transpose-columns-into-rows", "com.google.gridworks.commands.cell.TransposeColumnsIntoRowsCommand"}, {"transpose-columns-into-rows", "com.google.gridworks.commands.cell.TransposeColumnsIntoRowsCommand"},
{"transpose-rows-into-columns", "com.google.gridworks.commands.cell.TransposeRowsIntoColumnsCommand"},
{"add-column", "com.google.gridworks.commands.column.AddColumnCommand"}, {"add-column", "com.google.gridworks.commands.column.AddColumnCommand"},
{"remove-column", "com.google.gridworks.commands.column.RemoveColumnCommand"}, {"remove-column", "com.google.gridworks.commands.column.RemoveColumnCommand"},

View File

@ -0,0 +1,37 @@
package com.google.gridworks.commands.cell;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gridworks.commands.Command;
import com.google.gridworks.model.AbstractOperation;
import com.google.gridworks.model.Project;
import com.google.gridworks.operations.cell.TransposeRowsIntoColumnsOperation;
import com.google.gridworks.process.Process;
public class TransposeRowsIntoColumnsCommand extends Command {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Project project = getProject(request);
String columnName = request.getParameter("columnName");
int rowCount = Integer.parseInt(request.getParameter("rowCount"));
AbstractOperation op = new TransposeRowsIntoColumnsOperation(
columnName, rowCount);
Process process = op.createProcess(project, new Properties());
performProcessAndRespond(request, response, project, process);
} catch (Exception e) {
respondException(response, e);
}
}
}

View File

@ -14,6 +14,7 @@ import com.google.gridworks.operations.cell.MultiValuedCellJoinOperation;
import com.google.gridworks.operations.cell.MultiValuedCellSplitOperation; import com.google.gridworks.operations.cell.MultiValuedCellSplitOperation;
import com.google.gridworks.operations.cell.TextTransformOperation; import com.google.gridworks.operations.cell.TextTransformOperation;
import com.google.gridworks.operations.cell.TransposeColumnsIntoRowsOperation; import com.google.gridworks.operations.cell.TransposeColumnsIntoRowsOperation;
import com.google.gridworks.operations.cell.TransposeRowsIntoColumnsOperation;
import com.google.gridworks.operations.column.ColumnAdditionOperation; import com.google.gridworks.operations.column.ColumnAdditionOperation;
import com.google.gridworks.operations.column.ColumnMoveOperation; import com.google.gridworks.operations.column.ColumnMoveOperation;
import com.google.gridworks.operations.column.ColumnRemovalOperation; import com.google.gridworks.operations.column.ColumnRemovalOperation;
@ -54,6 +55,7 @@ public abstract class OperationRegistry {
register("multivalued-cell-split", MultiValuedCellSplitOperation.class); register("multivalued-cell-split", MultiValuedCellSplitOperation.class);
register("fill-down", FillDownOperation.class); register("fill-down", FillDownOperation.class);
register("transpose-columns-into-rows", TransposeColumnsIntoRowsOperation.class); register("transpose-columns-into-rows", TransposeColumnsIntoRowsOperation.class);
register("transpose-rows-into-columns", TransposeRowsIntoColumnsOperation.class);
register("column-addition", ColumnAdditionOperation.class); register("column-addition", ColumnAdditionOperation.class);
register("column-removal", ColumnRemovalOperation.class); register("column-removal", ColumnRemovalOperation.class);

View File

@ -0,0 +1,125 @@
package com.google.gridworks.operations.cell;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.gridworks.history.HistoryEntry;
import com.google.gridworks.model.AbstractOperation;
import com.google.gridworks.model.Cell;
import com.google.gridworks.model.Column;
import com.google.gridworks.model.Project;
import com.google.gridworks.model.Row;
import com.google.gridworks.model.changes.MassRowColumnChange;
import com.google.gridworks.operations.OperationRegistry;
public class TransposeRowsIntoColumnsOperation extends AbstractOperation {
final protected String _columnName;
final protected int _rowCount;
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
return new TransposeRowsIntoColumnsOperation(
obj.getString("columnName"),
obj.getInt("rowCount")
);
}
public TransposeRowsIntoColumnsOperation(
String columnName,
int rowCount
) {
_columnName = columnName;
_rowCount = rowCount;
}
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value("Transpose every " + _rowCount + " cells in column " + _columnName + " into separate columns");
writer.key("columnName"); writer.value(_columnName);
writer.key("rowCount"); writer.value(_rowCount);
writer.endObject();
}
protected String getBriefDescription(Project project) {
return "Transpose every " + _rowCount + " cells in column " + _columnName + " into separate columns";
}
@Override
protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
List<Column> newColumns = new ArrayList<Column>();
List<Column> oldColumns = project.columnModel.columns;
int columnIndex = project.columnModel.getColumnIndexByName(_columnName);
int columnCount = oldColumns.size();
newColumns.addAll(oldColumns.subList(0, columnIndex));
for (int i = 0; i < columnCount; i++) {
Column column = oldColumns.get(i);
if (i == columnIndex) {
int newIndex = 1;
for (int n = 0; n < _rowCount; n++) {
String columnName = _columnName + " " + newIndex++;
while (project.columnModel.getColumnByName(columnName) != null) {
columnName = _columnName + " " + newIndex++;
}
newColumns.add(new Column(i + n, columnName));
}
} else if (i < columnIndex) {
newColumns.add(new Column(i, column.getName()));
} else {
newColumns.add(new Column(i + _rowCount - 1, column.getName()));
}
}
List<Row> oldRows = project.rows;
List<Row> newRows = new ArrayList<Row>(oldRows.size() / _rowCount);
for (int r = 0; r < oldRows.size(); r += _rowCount) {
Row firstNewRow = new Row(newColumns.size());
for (int r2 = 0; r2 < _rowCount && r + r2 < oldRows.size(); r2++) {
Row oldRow = oldRows.get(r + r2);
Row newRow = r2 == 0 ? firstNewRow : new Row(newColumns.size());
boolean hasData = r2 == 0;
for (int c = 0; c < oldColumns.size(); c++) {
Column column = oldColumns.get(c);
Cell cell = oldRow.getCell(column.getCellIndex());
if (cell != null && cell.value != null) {
if (c == columnIndex) {
firstNewRow.setCell(columnIndex + r2, cell);
} else if (c < columnIndex) {
newRow.setCell(c, cell);
hasData = true;
} else {
newRow.setCell(c + _rowCount - 1, cell);
hasData = true;
}
}
}
if (hasData) {
newRows.add(newRow);
}
}
}
return new HistoryEntry(
historyEntryID,
project,
getBriefDescription(null),
this,
new MassRowColumnChange(newColumns, newRows)
);
}
}

View File

@ -352,6 +352,10 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
{ {
label: "Cells Across Columns into Rows", label: "Cells Across Columns into Rows",
click: function() { self._doTransposeColumnsIntoRows(); } click: function() { self._doTransposeColumnsIntoRows(); }
},
{
label: "Cells in Rows into Columns",
click: function() { self._doTransposeRowsIntoColumns(); }
} }
] ]
}, },
@ -1232,6 +1236,33 @@ DataTableColumnHeaderUI.prototype._doTransposeColumnsIntoRows = function() {
elmts.fromColumnSelect.bind("change", populateToColumn); elmts.fromColumnSelect.bind("change", populateToColumn);
}; };
DataTableColumnHeaderUI.prototype._doTransposeRowsIntoColumns = function() {
var rowCount = window.prompt("How many rows to transpose?", "2");
if (rowCount != null) {
try {
rowCount = parseInt(rowCount);
} catch (e) {
// ignore
}
if (isNaN(rowCount) || rowCount < 2) {
alert("Expected an integer at least 2.");
} else {
var config = {
columnName: this._column.name,
rowCount: rowCount
};
Gridworks.postProcess(
"transpose-rows-into-columns",
config,
null,
{ modelsChanged: true }
);
}
}
};
DataTableColumnHeaderUI.prototype._showSortingCriterion = function(criterion, hasOtherCriteria) { DataTableColumnHeaderUI.prototype._showSortingCriterion = function(criterion, hasOtherCriteria) {
var self = this; var self = this;