adding log-log support to the scatterplot matrix and more controls
(the scatterfacet still doesn't work but this is already more useful) git-svn-id: http://google-refine.googlecode.com/svn/trunk@456 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
7391f760db
commit
ba85f50e39
@ -30,8 +30,20 @@ import com.metaweb.gridworks.model.Row;
|
|||||||
|
|
||||||
public class ScatterplotCharter {
|
public class ScatterplotCharter {
|
||||||
|
|
||||||
private static final Color COLOR = Color.black;
|
private static final int LIN = 0;
|
||||||
|
private static final int LOG = 1;
|
||||||
|
private static final int RADIAL = 2;
|
||||||
|
|
||||||
|
private static int getAxisDim(String type) {
|
||||||
|
if ("log".equals(type)) {
|
||||||
|
return LOG;
|
||||||
|
} else if ("rad".equals(type) || "radial".equals(type)) {
|
||||||
|
return RADIAL;
|
||||||
|
} else {
|
||||||
|
return LIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
return "image/png";
|
return "image/png";
|
||||||
}
|
}
|
||||||
@ -47,23 +59,30 @@ public class ScatterplotCharter {
|
|||||||
|
|
||||||
class DrawingRowVisitor implements RowVisitor {
|
class DrawingRowVisitor implements RowVisitor {
|
||||||
|
|
||||||
private static final double px = 0.5f;
|
|
||||||
|
|
||||||
boolean process = true;
|
boolean process = true;
|
||||||
boolean smoothed = false;
|
|
||||||
|
|
||||||
int width = 50;
|
|
||||||
int height = 50;
|
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
int col_x;
|
int col_x;
|
||||||
int col_y;
|
int col_y;
|
||||||
|
int dim;
|
||||||
|
|
||||||
double w;
|
double w;
|
||||||
double h;
|
double h;
|
||||||
double min_x;
|
double min_x;
|
||||||
double min_y;
|
double min_y;
|
||||||
double max_x;
|
double max_x;
|
||||||
double max_y;
|
double max_y;
|
||||||
|
double delta_x;
|
||||||
|
double delta_y;
|
||||||
|
double log_delta_x;
|
||||||
|
double log_delta_y;
|
||||||
|
double rx;
|
||||||
|
double ry;
|
||||||
|
double dot;
|
||||||
|
|
||||||
|
Color color;
|
||||||
|
|
||||||
NumericBinIndex index_x;
|
NumericBinIndex index_x;
|
||||||
NumericBinIndex index_y;
|
NumericBinIndex index_y;
|
||||||
|
|
||||||
@ -76,8 +95,8 @@ public class ScatterplotCharter {
|
|||||||
if (column_x != null) {
|
if (column_x != null) {
|
||||||
col_x = column_x.getCellIndex();
|
col_x = column_x.getCellIndex();
|
||||||
index_x = getBinIndex(project, column_x);
|
index_x = getBinIndex(project, column_x);
|
||||||
min_x = index_x.getMin() * 1.1d;
|
min_x = index_x.getMin();
|
||||||
max_x = index_x.getMax() * 1.1d;
|
max_x = index_x.getMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
String col_y_name = o.getString("cy");
|
String col_y_name = o.getString("cy");
|
||||||
@ -85,12 +104,30 @@ public class ScatterplotCharter {
|
|||||||
if (column_y != null) {
|
if (column_y != null) {
|
||||||
col_y = column_y.getCellIndex();
|
col_y = column_y.getCellIndex();
|
||||||
index_y = getBinIndex(project, column_y);
|
index_y = getBinIndex(project, column_y);
|
||||||
min_y = index_y.getMin() * 1.1d;
|
min_y = index_y.getMin();
|
||||||
max_y = index_y.getMax() * 1.1d;
|
max_y = index_y.getMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
width = o.getInt("w");
|
width = (o.has("w")) ? o.getInt("w") : 20;
|
||||||
height = o.getInt("h");
|
height = (o.has("h")) ? o.getInt("h") : 20;
|
||||||
|
|
||||||
|
dot = (o.has("dot")) ? o.getDouble("dot") : 0.1d;
|
||||||
|
|
||||||
|
dim = (o.has("dim")) ? getAxisDim(o.getString("dim")) : LIN;
|
||||||
|
|
||||||
|
delta_x = max_x - min_x;
|
||||||
|
delta_y = max_y - min_y;
|
||||||
|
|
||||||
|
if (dim == RADIAL) {
|
||||||
|
rx = (o.has("rx")) ? o.getDouble("rx") : 0.0d;
|
||||||
|
ry = (o.has("ry")) ? o.getDouble("ry") : 0.0d;
|
||||||
|
} else if (dim == LOG) {
|
||||||
|
log_delta_x = Math.log10(delta_x);
|
||||||
|
log_delta_y = Math.log10(delta_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
String color_str = (o.has("color")) ? o.getString("color") : "000000";
|
||||||
|
color = new Color(Integer.parseInt(color_str,16));
|
||||||
|
|
||||||
w = (double) width;
|
w = (double) width;
|
||||||
h = (double) height;
|
h = (double) height;
|
||||||
@ -103,8 +140,8 @@ public class ScatterplotCharter {
|
|||||||
AffineTransform t = AffineTransform.getTranslateInstance(0,h);
|
AffineTransform t = AffineTransform.getTranslateInstance(0,h);
|
||||||
t.concatenate(AffineTransform.getScaleInstance(1.0d, -1.0d));
|
t.concatenate(AffineTransform.getScaleInstance(1.0d, -1.0d));
|
||||||
g2.setTransform(t);
|
g2.setTransform(t);
|
||||||
g2.setColor(COLOR);
|
g2.setColor(color);
|
||||||
g2.setPaint(COLOR);
|
g2.setPaint(color);
|
||||||
} else {
|
} else {
|
||||||
image = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
|
image = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
|
||||||
process = false;
|
process = false;
|
||||||
@ -112,10 +149,11 @@ public class ScatterplotCharter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private NumericBinIndex getBinIndex(Project project, Column column) {
|
private NumericBinIndex getBinIndex(Project project, Column column) {
|
||||||
String key = "numeric-bin:value";
|
String expression = "value";
|
||||||
|
String key = "numeric-bin:" + expression;
|
||||||
Evaluable eval = null;
|
Evaluable eval = null;
|
||||||
try {
|
try {
|
||||||
eval = MetaParser.parse("value");
|
eval = MetaParser.parse(expression);
|
||||||
} catch (ParsingException e) {
|
} catch (ParsingException e) {
|
||||||
// this should never happen
|
// this should never happen
|
||||||
}
|
}
|
||||||
@ -137,9 +175,20 @@ public class ScatterplotCharter {
|
|||||||
double xv = ((Number) cellx.value).doubleValue();
|
double xv = ((Number) cellx.value).doubleValue();
|
||||||
double yv = ((Number) celly.value).doubleValue();
|
double yv = ((Number) celly.value).doubleValue();
|
||||||
|
|
||||||
double x = (xv - min_x) * w / max_x;
|
double x;
|
||||||
double y = (yv - min_y) * h / max_y;
|
double y;
|
||||||
g2.fill(new Rectangle2D.Double(x, y, px, px));
|
|
||||||
|
if (dim == LOG) {
|
||||||
|
x = Math.log10(xv - min_x) * w / log_delta_x - dot / 2;
|
||||||
|
y = Math.log10(yv - min_y) * h / log_delta_y - dot / 2;
|
||||||
|
} else if (dim == RADIAL) {
|
||||||
|
x = (xv - min_x) * w / delta_x - dot / 2;
|
||||||
|
y = (yv - min_y) * h / delta_y - dot / 2;
|
||||||
|
} else {
|
||||||
|
x = (xv - min_x) * w / delta_x - dot / 2;
|
||||||
|
y = (yv - min_y) * h / delta_y - dot / 2;
|
||||||
|
}
|
||||||
|
g2.fill(new Rectangle2D.Double(x, y, dot, dot));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
function ScatterplotDialog() {
|
function ScatterplotDialog() {
|
||||||
this._createDialog();
|
this._createDialog();
|
||||||
|
this._plot_method = "lin";
|
||||||
|
this._plot_size = 20;
|
||||||
|
this._dot_size = 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScatterplotDialog.prototype._createDialog = function() {
|
ScatterplotDialog.prototype._createDialog = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var frame = DialogSystem.createDialog();
|
var frame = DialogSystem.createDialog();
|
||||||
frame.width("900px");
|
frame.width("1100px");
|
||||||
|
|
||||||
var header = $('<div></div>').addClass("dialog-header").text('Scatterplot Matrix').appendTo(frame);
|
var header = $('<div></div>').addClass("dialog-header").text('Scatterplot Matrix').appendTo(frame);
|
||||||
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
|
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
|
||||||
@ -17,29 +20,75 @@ ScatterplotDialog.prototype._createDialog = function() {
|
|||||||
'</tr></table>' +
|
'</tr></table>' +
|
||||||
'</div>'
|
'</div>'
|
||||||
).appendTo(frame);
|
).appendTo(frame);
|
||||||
|
|
||||||
var html = $(
|
var html = $(
|
||||||
'<div class="grid-layout layout-normal">' +
|
'<div class="grid-layout layout-normal"><table width="100%">' +
|
||||||
'<div bind="tableContainer" class="scatterplot-dialog-table-container"></div>' +
|
'<tr>' +
|
||||||
'</div>'
|
'<td>' +
|
||||||
|
'<span class="clustering-dialog-controls">Plot type: <select bind="plotSelector">' +
|
||||||
|
'<option selected="true">linear</option>' +
|
||||||
|
'<option>log-log</option>' +
|
||||||
|
'</select></span>' +
|
||||||
|
'<span class="clustering-dialog-controls">Plot Size: <input bind="plotSize" type="test" size="2" value="20"> px</span>' +
|
||||||
|
'<span class="clustering-dialog-controls">Dot Size: <input bind="dotSize" type="test" size="2" value="0.1"> px</span>' +
|
||||||
|
'</td>' +
|
||||||
|
'</tr>' +
|
||||||
|
'<tr>' +
|
||||||
|
'<td>' +
|
||||||
|
'<div bind="tableContainer" class="scatterplot-dialog-table-container"></div>' +
|
||||||
|
'</td>' +
|
||||||
|
'</tr>' +
|
||||||
|
'</table></div>'
|
||||||
).appendTo(body);
|
).appendTo(body);
|
||||||
|
|
||||||
|
|
||||||
this._elmts = DOM.bind(html);
|
this._elmts = DOM.bind(html);
|
||||||
|
|
||||||
|
this._elmts.plotSelector.change(function() {
|
||||||
|
var selection = $(this).find("option:selected").text();
|
||||||
|
if (selection == 'linear') {
|
||||||
|
self._plot_method = "lin";
|
||||||
|
} else if (selection === 'log-log') {
|
||||||
|
self._plot_method = "log";
|
||||||
|
}
|
||||||
|
self._renderMatrix();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._elmts.plotSize.change(function() {
|
||||||
|
try {
|
||||||
|
self._plot_size = parseInt($(this).val())
|
||||||
|
self._renderMatrix();
|
||||||
|
} catch (e) {
|
||||||
|
alert("Must be a number");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this._elmts.dotSize.change(function() {
|
||||||
|
try {
|
||||||
|
self._dot_size = parseFloat($(this).val())
|
||||||
|
self._renderMatrix();
|
||||||
|
} catch (e) {
|
||||||
|
alert("Must be a number");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var left_footer = footer.find(".left");
|
var left_footer = footer.find(".left");
|
||||||
|
|
||||||
var right_footer = footer.find(".right");
|
var right_footer = footer.find(".right");
|
||||||
$('<button></button>').text("Close").click(function() { self._dismiss(); }).appendTo(right_footer);
|
$('<button></button>').text("Close").click(function() { self._dismiss(); }).appendTo(right_footer);
|
||||||
|
|
||||||
this._renderMatrix(theProject.columnModel.columns);
|
|
||||||
this._level = DialogSystem.showDialog(frame);
|
this._level = DialogSystem.showDialog(frame);
|
||||||
|
this._renderMatrix();
|
||||||
};
|
};
|
||||||
|
|
||||||
ScatterplotDialog.prototype._renderMatrix = function(columns) {
|
ScatterplotDialog.prototype._renderMatrix = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
var columns = theProject.columnModel.columns;
|
||||||
|
|
||||||
var container = this._elmts.tableContainer;
|
var container = this._elmts.tableContainer.html(
|
||||||
|
'<div style="margin: 1em; font-size: 130%; color: #888;">Processing... <img src="/images/small-spinner.gif"></div>'
|
||||||
|
);
|
||||||
|
|
||||||
if (columns.length > 0) {
|
if (columns.length > 0) {
|
||||||
var table = $('<table></table>').addClass("scatterplot-matrix-table")[0];
|
var table = $('<table></table>').addClass("scatterplot-matrix-table")[0];
|
||||||
|
|
||||||
@ -51,8 +100,10 @@ ScatterplotDialog.prototype._renderMatrix = function(columns) {
|
|||||||
var plotter_params = {
|
var plotter_params = {
|
||||||
'cx' : cx.name,
|
'cx' : cx.name,
|
||||||
'cy' : cy.name,
|
'cy' : cy.name,
|
||||||
'w' : 20,
|
'w' : self._plot_size,
|
||||||
'h' : 20
|
'h' : self._plot_size,
|
||||||
|
'dot': self._dot_size,
|
||||||
|
'dim': self._plot_method
|
||||||
};
|
};
|
||||||
var params = {
|
var params = {
|
||||||
project: theProject.id,
|
project: theProject.id,
|
||||||
|
@ -4,12 +4,15 @@
|
|||||||
border: 1px solid #aaa;
|
border: 1px solid #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clustering-dialog-controls {
|
||||||
|
margin-right: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
table.scatterplot-matrix-table {
|
table.scatterplot-matrix-table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.scatterplot-matrix-table > tbody > tr > td {
|
table.scatterplot-matrix-table > tbody > tr > td {
|
||||||
padding: 2px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user