More work on the schema alignment node dialog.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@90 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-02-12 02:23:26 +00:00
parent f5942773ec
commit 634d666949
6 changed files with 266 additions and 140 deletions

View File

@ -16,8 +16,11 @@ public class AnonymousNode implements Node {
public void write(JSONWriter writer, Properties options) public void write(JSONWriter writer, Properties options)
throws JSONException { throws JSONException {
// TODO Auto-generated method stub
writer.object();
writer.key("nodeType"); writer.value("anonymous");
writer.key("type"); type.write(writer, options);
writer.endObject();
} }
} }

View File

@ -149,6 +149,14 @@ SchemaAlignmentDialog.prototype._renderFooter = function(footer) {
SchemaAlignmentDialog.prototype._renderBody = function(body) { SchemaAlignmentDialog.prototype._renderBody = function(body) {
var self = this; var self = this;
$('<p>' +
'The protograph serves as a skeleton for the graph-shaped data that will get generated ' +
'from your grid-shaped data and written into Freebase. The cells in each record of your data will ' +
'get placed into nodes within the protograph. Configure the protograph by specifying which ' +
'column to substitute into which node. A node can also be an automatically generated ' +
'anonymous node, or it can be an explicit value or topic that is the same for all records.' +
'</p>').appendTo(body);
this._canvas = $('<div></div>').addClass("schema-alignment-dialog-canvas").appendTo(body); this._canvas = $('<div></div>').addClass("schema-alignment-dialog-canvas").appendTo(body);
this._nodeTable = $('<table></table>').addClass("schema-alignment-table-layout").appendTo(this._canvas)[0]; this._nodeTable = $('<table></table>').addClass("schema-alignment-table-layout").appendTo(this._canvas)[0];
@ -418,96 +426,125 @@ SchemaAlignmentDialog.UINode.prototype._showTagDialog = function() {
*/ */
var html = $( var html = $(
'<table>' + '<table class="schema-align-node-dialog-layout">' +
'<tr>' + '<tr>' +
'<td>' + '<td>' +
'<p><input type="radio" name="schema-align-node-dialog-node-type" value="cell-as" id="radioCellAs" /> Set to Cell in Column</p>' + '<table class="schema-align-node-dialog-layout2">' +
'<table>' + '<tr>' +
'<td colspan="3">' +
'<div class="schema-align-node-dialog-node-type">' +
'<input type="radio" name="schema-align-node-dialog-node-type" value="anonymous" id="radioNodeTypeAnonymous" /> Generate an anonymous graph node' +
'</div>' +
'</td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>Assign a type to the node</td>' +
'<td>&nbsp;<input id="anonymousNodeTypeInput" /></td>' +
'</tr>' +
'<tr>' +
'<td colspan="3">' +
'<div class="schema-align-node-dialog-node-type">' +
'<input type="radio" name="schema-align-node-dialog-node-type" value="topic" id="radioNodeTypeTopic" /> Use one existing Freebase topic' +
'</div>' +
'</td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>Topic</td>' +
'<td><input id="topicNodeTypeInput" /></td>' +
'</tr>' +
'<tr>' +
'<td colspan="3">' +
'<div class="schema-align-node-dialog-node-type">' +
'<input type="radio" name="schema-align-node-dialog-node-type" value="value" id="radioNodeTypeValue" /> Use a literal value' +
'</div>' +
'</td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>Value</td>' +
'<td><input id="valueNodeTypeValueInput" /></td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>Value type</td>' +
'<td><input id="valueNodeTypeValueTypeInput" /></td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>Language</td>' +
'<td><input id="valueNodeTypeLanguageInput" /></td>' +
'</tr>' +
'</table>' +
'</td>' +
'<td>' +
'<table class="schema-align-node-dialog-layout2">' +
'<tr>' +
'<td>' +
'<div class="schema-align-node-dialog-node-type">' +
'<input type="radio" name="schema-align-node-dialog-node-type" value="cell-as" id="radioNodeTypeCellAs" /> Set to Cell in Column' +
'</div>' +
'</td>' +
'</tr>' +
'<tr>' +
'<td>' +
'<table class="schema-align-node-dialog-layout2">' +
'<tr>' + '<tr>' +
'<td><div class="schema-alignment-node-dialog-column-list" id="divColumns"></div></td>' + '<td><div class="schema-alignment-node-dialog-column-list" id="divColumns"></div></td>' +
'<td>' + '<td>' +
'<p>The cell\'s content will be ...</p>' + '<table class="schema-align-node-dialog-layout2" cols="4">' +
'<table>' +
'<tr>' + '<tr>' +
'<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-topic" id="radioCellAsTopic" /></td>' + '<td colspan="4">The cell\'s content is used ...</td>' +
'<td colspan="2">name of a topic (as reconciled)</td>' + '</tr>' +
'<tr>' +
'<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-topic" id="radioNodeTypeCellAsTopic" /></td>' +
'<td colspan="3">to specify a Freebase topic, as reconciled</td>' +
'</tr>' + '</tr>' +
'<tr>' + '<tr>' +
'<td></td>' + '<td></td>' +
'<td>of Freebase type</td>' + '<td colspan="1" width="1%"><input type="checkbox" id="radioNodeTypeCellAsTopicCreate" /></td>' +
'<td><input /></td>' + '<td colspan="2">If not reconciled, create new topic named by the cell\'s content, and assign it a type</td>' +
'</tr>' + '</tr>' +
'<tr>' + '<tr>' +
'<td></td>' + '<td></td>' +
'<td>create new topic if not reconciled</td>' + '<td></td>' +
'<td><input type="checkbox" /></td>' + '<td colspan="1">Type:</td>' +
'<td colspan="1"><input id="cellAsTopicNodeTypeInput" /></td>' +
'</tr>' + '</tr>' +
'<tr>' + '<tr>' +
'<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-value" id="radioCellAsValue" /></td>' + '<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-value" id="radioNodeTypeCellAsValue" /></td>' +
'<td colspan="2">a literal value</td>' + '<td colspan="3">as a literal value</td>' +
'</tr>' + '</tr>' +
'<tr>' + '<tr>' +
'<td></td>' + '<td></td>' +
'<td>of literal type</td>' + '<td colspan="2">Literal type</td>' +
'<td><input /></td>' + '<td colspan="1"><input id="cellAsValueTypeInput" /></td>' +
'</tr>' + '</tr>' +
'<tr>' + '<tr>' +
'<td></td>' + '<td></td>' +
'<td>in language</td>' + '<td colspan="2">Language (for text)</td>' +
'<td><input /></td>' + '<td colspan="1"><input id="cellAsValueLanguageInput" /></td>' +
'</tr>' + '</tr>' +
'<tr>' + '<tr>' +
'<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-key" id="radioCellAsKey" /></td>' + '<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-key" id="radioNodeTypeCellAsKey" /></td>' +
'<td colspan="2">a key in a namespace</td>' + '<td colspan="3">as a key in a namespace</td>' +
'</tr>' + '</tr>' +
'<tr>' + '<tr>' +
'<td></td>' + '<td></td>' +
'<td>in namespace</td>' + '<td colspan="2">Namespace</td>' +
'<td><input /></td>' + '<td colspan="1"><input id="cellAsKeyInput" /></td>' +
'</tr>' + '</tr>' +
'</table>' + '</table>' +
'</td>' + '</td>' +
'</tr>' + '</tr>' +
'</table>' + '</table>' +
'</td>' + '</td>' +
'<td>' +
'<p><input type="radio" name="schema-align-node-dialog-node-type" value="anonymous" id="radioAnonymous" /> Set to Anonymous Node</p>' +
'<table>' +
'<tr>' +
'<td></td>' +
'<td>of Freebase type</td>' +
'<td><input /></td>' +
'</tr>' +
'</table>' +
'<p><input type="radio" name="schema-align-node-dialog-node-type" value="topic" id="radioTopic" /> Set to Freebase Topic</p>' +
'<table>' +
'<tr>' +
'<td></td>' +
'<td>topic</td>' +
'<td><input /></td>' +
'</tr>' +
'</table>' +
'<p><input type="radio" name="schema-align-node-dialog-node-type" value="value" id="radioValue" /> Set to Literal Value</p>' +
'<table>' +
'<tr>' +
'<td></td>' +
'<td>value</td>' +
'<td><input /></td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>value type</td>' +
'<td><input /></td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>lang</td>' +
'<td><input /></td>' +
'</tr>' + '</tr>' +
'</table>' + '</table>' +
'</td>' + '</td>' +
@ -515,39 +552,117 @@ SchemaAlignmentDialog.UINode.prototype._showTagDialog = function() {
'</table>' '</table>'
).appendTo(body); ).appendTo(body);
var elmtMap = DOM.bind(html, [ "divColumns" ]); var elmts = DOM.bind(html);
var makeColumnChoice = function(column) { var tableColumns = $('<table></table>')
var div = $('<div></div>') .attr("cellspacing", "5")
.addClass("schema-alignment-node-dialog-column-choice") .attr("cellpadding", "0")
.appendTo(elmtMap.divColumns); .appendTo(elmts.divColumns)[0];
var makeColumnChoice = function(column, columnIndex) {
var tr = tableColumns.insertRow(tableColumns.rows.length);
var radio = $('<input />') var radio = $('<input />')
.attr("type", "radio") .attr("type", "radio")
.attr("value", column.cellIndex) .attr("value", column.cellIndex)
.attr("name", "schema-align-node-dialog-column") .attr("name", "schema-align-node-dialog-column")
.appendTo(div); .appendTo(tr.insertCell(0))
.click(function() {
elmts.radioNodeTypeCellAs[0].checked = true;
});
if (column.cellIndex == self._node.cellIndex) { if ((!("cellIndex" in self._node) || self._node.cellIndex == null) && columnIndex == 0) {
radio.attr("checked", "true");
} else if (column.cellIndex == self._node.cellIndex) {
radio.attr("checked", "true"); radio.attr("checked", "true");
} }
$('<span></span>').text(column.headerLabel).appendTo(div); $('<span></span>').text(column.headerLabel).appendTo(tr.insertCell(1));
}; };
var columns = theProject.columnModel.columns; var columns = theProject.columnModel.columns;
for (var i = 0; i < columns.length; i++) { for (var i = 0; i < columns.length; i++) {
makeColumnChoice(columns[i]); makeColumnChoice(columns[i], i);
} }
elmts.anonymousNodeTypeInput
.bind("focus", function() { elmts.radioNodeTypeAnonymous[0].checked = true; })
.suggest({ type: "/type/type" });
elmts.topicNodeTypeInput
.bind("focus", function() { elmts.radioNodeTypeTopic[0].checked = true; })
.suggest({});
elmts.valueNodeTypeValueInput
.bind("focus", function() { elmts.radioNodeTypeValue[0].checked = true; })
elmts.valueNodeTypeValueTypeInput
.bind("focus", function() { elmts.radioNodeTypeValue[0].checked = true; })
elmts.valueNodeTypeLanguageInput
.bind("focus", function() { elmts.radioNodeTypeValue[0].checked = true; })
elmts.radioNodeTypeCellAsTopicCreate
.click(function() {
elmts.radioNodeTypeCellAs[0].checked = true;
elmts.radioNodeTypeCellAsTopic[0].checked = true;
});
elmts.cellAsTopicNodeTypeInput
.bind("focus", function() {
elmts.radioNodeTypeCellAs[0].checked = true;
elmts.radioNodeTypeCellAsTopic[0].checked = true;
})
.suggest({ type: "/type/type" });
elmts.cellAsValueTypeInput
.bind("focus", function() {
elmts.radioNodeTypeCellAs[0].checked = true;
elmts.radioNodeTypeCellAsValue[0].checked = true;
})
elmts.cellAsValueLanguageInput
.bind("focus", function() {
elmts.radioNodeTypeCellAs[0].checked = true;
elmts.radioNodeTypeCellAsValue[0].checked = true;
})
elmts.cellAsKeyInput
.bind("focus", function() {
elmts.radioNodeTypeCellAs[0].checked = true;
elmts.radioNodeTypeCellAsKey[0].checked = true;
})
.suggest({ type: "/type/namespace" });
if (this._node.nodeType.match(/^cell-as-/)) {
elmts.radioNodeTypeCellAs[0].checked = true;
if (this._node.nodeType == "cell-as-topic") {
elmts.radioNodeTypeCellAsTopic[0].checked = true;
} else if (this._node.nodeType == "cell-as-value") {
elmts.radioNodeTypeCellAsValue[0].checked = true;
} else if (this._node.nodeType == "cell-as-key") {
elmts.radioNodeTypeCellAsKey[0].checked = true;
}
} else if (this._node.nodeType == "anonymous") {
elmts.radioNodeTypeAnonymous[0].checked = true;
} else if (this._node.nodeType == "topic") {
elmts.radioNodeTypeTopic[0].checked = true;
} else if (this._node.nodeType == "value") {
elmts.radioNodeTypeValue[0].checked = true;
}
/*-------------------------------------------------- /*--------------------------------------------------
* Footer * Footer
*-------------------------------------------------- *--------------------------------------------------
*/ */
var getResultJSON = function() {
};
$('<button></button>').html("&nbsp;&nbsp;OK&nbsp;&nbsp;").click(function() { $('<button></button>').html("&nbsp;&nbsp;OK&nbsp;&nbsp;").click(function() {
DialogSystem.dismissUntil(level - 1); DialogSystem.dismissUntil(level - 1);
self._onDone(self._getNewProtograph()); self._node = getResultJSON();
if (self._isExpandable()) {
self._showExpandable();
} else {
hide._showExpandable();
}
self._renderMain();
}).appendTo(footer); }).appendTo(footer);
$('<button></button>').text("Cancel").click(function() { $('<button></button>').text("Cancel").click(function() {

View File

@ -1,18 +1,10 @@
DialogSystem = { DialogSystem = {
_layers: [], _layers: []
_bottomOverlay: null
}; };
DialogSystem.showDialog = function(elmt, onCancel) { DialogSystem.showDialog = function(elmt, onCancel) {
if (DialogSystem._bottomOverlay == null) {
DialogSystem._bottomOverlay = $('<div>&nbsp;</div>')
.addClass("dialog-overlay")
.css("z-index", 100)
.appendTo(document.body);
}
var overlay = $('<div>&nbsp;</div>') var overlay = $('<div>&nbsp;</div>')
.addClass("dialog-overlay2") .addClass("dialog-overlay")
.css("z-index", 101 + DialogSystem._layers.length * 2) .css("z-index", 101 + DialogSystem._layers.length * 2)
.appendTo(document.body); .appendTo(document.body);
@ -55,13 +47,6 @@ DialogSystem.dismissUntil = function(level) {
} }
} }
DialogSystem._layers = DialogSystem._layers.slice(0, level); DialogSystem._layers = DialogSystem._layers.slice(0, level);
if (level == 0) {
if (DialogSystem._bottomOverlay != null) {
DialogSystem._bottomOverlay.remove();
DialogSystem._bottomOverlay = null;
}
}
}; };
DialogSystem.createDialog = function() { DialogSystem.createDialog = function() {

View File

@ -1,10 +1,7 @@
var DOM = {}; var DOM = {};
DOM.bind = function(elmt, fields) { DOM.bind = function(elmt) {
var map = {}; var map = {};
for (var i = 0; i < fields.length; i++) {
map[fields[i]] = null;
}
DOM._bindDOMChildren(elmt[0], map); DOM._bindDOMChildren(elmt[0], map);
@ -14,11 +11,9 @@ DOM.bind = function(elmt, fields) {
DOM._bindDOMElement = function(elmt, map) { DOM._bindDOMElement = function(elmt, map) {
var id = elmt.id; var id = elmt.id;
if (id != null && id.length > 0) { if (id != null && id.length > 0) {
if (id in map && map.hasOwnProperty(id)) {
map[id] = $(elmt); map[id] = $(elmt);
elmt.removeAttribute("id"); elmt.removeAttribute("id");
} }
}
if (elmt.hasChildNodes()) { if (elmt.hasChildNodes()) {
DOM._bindDOMChildren(elmt, map); DOM._bindDOMChildren(elmt, map);

View File

@ -1,25 +1,13 @@
.dialog-overlay { .dialog-overlay {
position: fixed;
padding: 0px;
margin: 0px;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: black; background: black;
opacity: 0.3; opacity: 0.3;
position: fixed;
padding: 0px;
margin: 0px;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
.dialog-overlay2 {
position: fixed;
padding: 0px;
margin: 0px;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: black;
opacity: 0.01;
} }
.dialog-container { .dialog-container {

View File

@ -64,12 +64,52 @@ a.schema-alignment-link-tag:hover {
color: #88f; color: #88f;
} }
/*--------------------------------------------------
* Node dialog
*--------------------------------------------------
*/
table.schema-align-node-dialog-layout {
border-collapse: collapse;
}
table.schema-align-node-dialog-layout > tbody > tr > td {
padding-right: 1.5em;
padding-bottom: 1.5em;
vertical-align: baseline;
}
table.schema-align-node-dialog-layout > tbody > tr > td:last-child {
padding-right: 0;
}
table.schema-align-node-dialog-layout > tbody > tr:last-child > td {
padding-bottom: 0;
}
table.schema-align-node-dialog-layout2 {
border-collapse: collapse;
}
table.schema-align-node-dialog-layout2 > tbody > tr > td {
padding-right: 0.75em;
padding-bottom: 0.75em;
vertical-align: baseline;
}
table.schema-align-node-dialog-layout2 > tbody > tr > td:last-child {
padding-right: 0;
}
table.schema-align-node-dialog-layout2 > tbody > tr:last-child > td {
padding-bottom: 0;
}
.schema-align-node-dialog-node-type {
padding: 0.25em;
background: #ddf;
-moz-border-radius: 0.5em;
}
.schema-align-node-dialog-node-type input {
vertical-align: text-bottom;
}
.schema-alignment-node-dialog-column-list { .schema-alignment-node-dialog-column-list {
height: 300px; height: 300px;
width: 200px;
overflow: auto; overflow: auto;
border: 1px solid #aaa; border: 1px solid #ddd;
padding: 2px;
}
.schema-alignment-node-dialog-column-choice {
margin: 5px;
} }