fixe rotation parsing in scatterplot facet (#3926)

* fixes #3344

* Remove try/catch block no longer useful
This commit is contained in:
Warpeas 2021-05-26 20:08:42 +08:00 committed by GitHub
parent dd4eb781e1
commit 3adc03c0db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 112 additions and 68 deletions

View File

@ -65,110 +65,106 @@ import com.google.refine.util.ParsingUtilities;
public class GetScatterplotCommand extends Command { public class GetScatterplotCommand extends Command {
final static Logger logger = LoggerFactory.getLogger("get-scatterplot_command"); final static Logger logger = LoggerFactory.getLogger("get-scatterplot_command");
@Override @Override
public void doGet(HttpServletRequest request, HttpServletResponse response) public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { throws ServletException, IOException {
try { try {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
Project project = getProject(request); Project project = getProject(request);
Engine engine = getEngine(request, project); Engine engine = getEngine(request, project);
PlotterConfig conf = ParsingUtilities.mapper.readValue( PlotterConfig conf = ParsingUtilities.mapper.readValue(
request.getParameter("plotter"), request.getParameter("plotter"),
PlotterConfig.class); PlotterConfig.class);
response.setHeader("Content-Type", "image/png"); response.setHeader("Content-Type", "image/png");
ServletOutputStream sos = null; ServletOutputStream sos = null;
try { try {
sos = response.getOutputStream(); sos = response.getOutputStream();
draw(sos, project, engine, conf); draw(sos, project, engine, conf);
} finally { } finally {
sos.close(); sos.close();
} }
logger.trace("Drawn scatterplot in {} ms", Long.toString(System.currentTimeMillis() - start)); logger.trace("Drawn scatterplot in {} ms", Long.toString(System.currentTimeMillis() - start));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
respondException(response, e); respondException(response, e);
} }
} }
protected static class PlotterConfig { protected static class PlotterConfig {
@JsonProperty(ScatterplotFacet.SIZE) @JsonProperty(ScatterplotFacet.SIZE)
public int size = 100; public int size = 100;
@JsonProperty(ScatterplotFacet.DOT) @JsonProperty(ScatterplotFacet.DOT)
double dot = 100; double dot = 100;
@JsonIgnore @JsonIgnore
public int dim_x = ScatterplotFacet.LIN; public int dim_x = ScatterplotFacet.LIN;
@JsonIgnore @JsonIgnore
public int dim_y = ScatterplotFacet.LIN; public int dim_y = ScatterplotFacet.LIN;
@JsonProperty(ScatterplotFacet.ROTATION) @JsonProperty(ScatterplotFacet.ROTATION)
public int rotation = ScatterplotFacet.NO_ROTATION; public int rotation = ScatterplotFacet.NO_ROTATION;
@JsonProperty(ScatterplotFacet.COLOR) @JsonProperty(ScatterplotFacet.COLOR)
public String color_str = "000000"; public String color_str = "000000";
@JsonProperty(ScatterplotFacet.BASE_COLOR) @JsonProperty(ScatterplotFacet.BASE_COLOR)
public String base_color_str = null; public String base_color_str = null;
@JsonProperty(ScatterplotFacet.X_COLUMN_NAME) @JsonProperty(ScatterplotFacet.X_COLUMN_NAME)
public String columnName_x = ""; public String columnName_x = "";
@JsonProperty(ScatterplotFacet.X_EXPRESSION) @JsonProperty(ScatterplotFacet.X_EXPRESSION)
public String expression_x = "value"; public String expression_x = "value";
@JsonProperty(ScatterplotFacet.Y_COLUMN_NAME) @JsonProperty(ScatterplotFacet.Y_COLUMN_NAME)
public String columnName_y = ""; public String columnName_y = "";
@JsonProperty(ScatterplotFacet.Y_EXPRESSION) @JsonProperty(ScatterplotFacet.Y_EXPRESSION)
public String expression_y = "value"; public String expression_y = "value";
@JsonProperty(ScatterplotFacet.DIM_X) @JsonProperty(ScatterplotFacet.DIM_X)
public String getDimX() { public String getDimX() {
return dim_x == ScatterplotFacet.LIN ? "lin" : "log"; return dim_x == ScatterplotFacet.LIN ? "lin" : "log";
} }
@JsonProperty(ScatterplotFacet.DIM_Y) @JsonProperty(ScatterplotFacet.DIM_Y)
public String getDimY() { public String getDimY() {
return dim_y == ScatterplotFacet.LIN ? "lin" : "log"; return dim_y == ScatterplotFacet.LIN ? "lin" : "log";
} }
@JsonProperty(ScatterplotFacet.DIM_X) @JsonProperty(ScatterplotFacet.DIM_X)
public void setDimX(String dim) { public void setDimX(String dim) {
dim_x = dim.equals("lin") ? ScatterplotFacet.LIN : ScatterplotFacet.LOG; dim_x = dim.equals("lin") ? ScatterplotFacet.LIN : ScatterplotFacet.LOG;
} }
@JsonProperty(ScatterplotFacet.DIM_Y) @JsonProperty(ScatterplotFacet.DIM_Y)
public void setDimY(String dim) { public void setDimY(String dim) {
dim_y = dim.equals("lin") ? ScatterplotFacet.LIN : ScatterplotFacet.LOG; dim_y = dim.equals("lin") ? ScatterplotFacet.LIN : ScatterplotFacet.LOG;
} }
// rotation can be set to "none" (a JSON string) in which case it should be ignored // rotation can be set to "none" (a JSON string) in which case it should be ignored
@JsonProperty(ScatterplotFacet.ROTATION) @JsonProperty(ScatterplotFacet.ROTATION)
public void setRotation(Object rotation) { public void setRotation(Object rotation) {
try { this.rotation = ScatterplotFacet.ScatterplotFacetConfig.getRotation(rotation.toString());
this.rotation = Integer.parseInt(rotation.toString());
} catch(NumberFormatException e) {
;
}
} }
} }
public void draw(OutputStream output, Project project, Engine engine, PlotterConfig o) throws IOException { public void draw(OutputStream output, Project project, Engine engine, PlotterConfig o) throws IOException {
double min_x = 0; double min_x = 0;
double min_y = 0; double min_y = 0;
double max_x = 0; double max_x = 0;
double max_y = 0; double max_y = 0;
int columnIndex_x = 0; int columnIndex_x = 0;
int columnIndex_y = 0; int columnIndex_y = 0;
Evaluable eval_x = null; Evaluable eval_x = null;
Evaluable eval_y = null; Evaluable eval_y = null;
Color color = new Color(Integer.parseInt(o.color_str,16)); Color color = new Color(Integer.parseInt(o.color_str, 16));
Color base_color = o.base_color_str != null ? new Color(Integer.parseInt(o.base_color_str,16)) : null; Color base_color = o.base_color_str != null ? new Color(Integer.parseInt(o.base_color_str, 16)) : null;
if (o.columnName_x.length() > 0) { if (o.columnName_x.length() > 0) {
Column x_column = project.columnModel.getColumnByName(o.columnName_x); Column x_column = project.columnModel.getColumnByName(o.columnName_x);
if (x_column != null) { if (x_column != null) {
@ -177,13 +173,13 @@ public class GetScatterplotCommand extends Command {
} else { } else {
columnIndex_x = -1; columnIndex_x = -1;
} }
try { try {
eval_x = MetaParser.parse(o.expression_x); eval_x = MetaParser.parse(o.expression_x);
} catch (ParsingException e) { } catch (ParsingException e) {
logger.warn("error parsing expression", e); logger.warn("error parsing expression", e);
} }
if (o.columnName_y.length() > 0) { if (o.columnName_y.length() > 0) {
Column y_column = project.columnModel.getColumnByName(o.columnName_y); Column y_column = project.columnModel.getColumnByName(o.columnName_y);
if (y_column != null) { if (y_column != null) {
@ -192,16 +188,16 @@ public class GetScatterplotCommand extends Command {
} else { } else {
columnIndex_y = -1; columnIndex_y = -1;
} }
try { try {
eval_y = MetaParser.parse(o.expression_y); eval_y = MetaParser.parse(o.expression_y);
} catch (ParsingException e) { } catch (ParsingException e) {
logger.warn("error parsing expression", e); logger.warn("error parsing expression", e);
} }
NumericBinIndex index_x = null; NumericBinIndex index_x = null;
NumericBinIndex index_y = null; NumericBinIndex index_y = null;
Column column_x = project.columnModel.getColumnByName(o.columnName_x); Column column_x = project.columnModel.getColumnByName(o.columnName_x);
if (column_x != null) { if (column_x != null) {
columnIndex_x = column_x.getCellIndex(); columnIndex_x = column_x.getCellIndex();
@ -217,32 +213,32 @@ public class GetScatterplotCommand extends Command {
min_y = index_y.getMin(); min_y = index_y.getMin();
max_y = index_y.getMax(); max_y = index_y.getMax();
} }
if (index_x != null && index_y != null && index_x.isNumeric() && index_y.isNumeric()) { if (index_x != null && index_y != null && index_x.isNumeric() && index_y.isNumeric()) {
ScatterplotDrawingRowVisitor drawer = new ScatterplotDrawingRowVisitor( ScatterplotDrawingRowVisitor drawer = new ScatterplotDrawingRowVisitor(
columnIndex_x, columnIndex_y, min_x, max_x, min_y, max_y, columnIndex_x, columnIndex_y, min_x, max_x, min_y, max_y,
o.size, o.dim_x, o.dim_y, o.rotation, o.dot, color o.size, o.dim_x, o.dim_y, o.rotation, o.dot, color
); );
if (base_color != null) { if (base_color != null) {
drawer.setColor(base_color); drawer.setColor(base_color);
FilteredRows filteredRows = engine.getAllRows(); FilteredRows filteredRows = engine.getAllRows();
filteredRows.accept(project, drawer); filteredRows.accept(project, drawer);
drawer.setColor(color); drawer.setColor(color);
} }
{ {
FilteredRows filteredRows = engine.getAllFilteredRows(); FilteredRows filteredRows = engine.getAllFilteredRows();
filteredRows.accept(project, drawer); filteredRows.accept(project, drawer);
} }
ImageIO.write(drawer.getImage(), "png", output); ImageIO.write(drawer.getImage(), "png", output);
} else { } else {
ImageIO.write(new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR), "png", output); ImageIO.write(new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR), "png", output);
} }
} }
} }

View File

@ -75,6 +75,42 @@ public class ScatterplotDrawCommandTests {
+ "\"from_y\":0," + "\"from_y\":0,"
+ "\"to_y\":0," + "\"to_y\":0,"
+ "\"color\":\"ff6a00\"}"; + "\"color\":\"ff6a00\"}";
public static String configJsonWithCW = "{"
+ "\"name\":\"b (x) vs. y (y)\","
+ "\"cx\":\"b\","
+ "\"cy\":\"y\","
+ "\"l\":150,"
+ "\"ex\":\"value\","
+ "\"ey\":\"value\","
+ "\"dot\":1.4,"
+ "\"dim_x\":\"lin\","
+ "\"dim_y\":\"lin\","
+ "\"r\":\"cw\","
+ "\"type\":\"scatterplot\","
+ "\"from_x\":0,"
+ "\"to_x\":0,"
+ "\"from_y\":0,"
+ "\"to_y\":0,"
+ "\"color\":\"ff6a00\"}";
public static String configJsonWithCCW = "{"
+ "\"name\":\"b (x) vs. y (y)\","
+ "\"cx\":\"b\","
+ "\"cy\":\"y\","
+ "\"l\":150,"
+ "\"ex\":\"value\","
+ "\"ey\":\"value\","
+ "\"dot\":1.4,"
+ "\"dim_x\":\"lin\","
+ "\"dim_y\":\"lin\","
+ "\"r\":\"ccw\","
+ "\"type\":\"scatterplot\","
+ "\"from_x\":0,"
+ "\"to_x\":0,"
+ "\"from_y\":0,"
+ "\"to_y\":0,"
+ "\"color\":\"ff6a00\"}";
@Test @Test
public void testParseConfig() throws JsonParseException, JsonMappingException, IOException { public void testParseConfig() throws JsonParseException, JsonMappingException, IOException {
@ -88,7 +124,19 @@ public class ScatterplotDrawCommandTests {
@Test @Test
public void testParseConfigWithNone() throws JsonParseException, JsonMappingException, IOException { public void testParseConfigWithNone() throws JsonParseException, JsonMappingException, IOException {
GetScatterplotCommand.PlotterConfig config = ParsingUtilities.mapper.readValue(configJsonWithNone, GetScatterplotCommand.PlotterConfig.class); GetScatterplotCommand.PlotterConfig config = ParsingUtilities.mapper.readValue(configJsonWithNone, GetScatterplotCommand.PlotterConfig.class);
Assert.assertEquals(0, config.rotation); Assert.assertEquals(ScatterplotFacet.NO_ROTATION, config.rotation);
} }
@Test
public void testParseConfigWithCW() throws JsonParseException, JsonMappingException, IOException {
GetScatterplotCommand.PlotterConfig config = ParsingUtilities.mapper.readValue(configJsonWithCW, GetScatterplotCommand.PlotterConfig.class);
Assert.assertEquals(ScatterplotFacet.ROTATE_CW, config.rotation);
}
@Test
public void testParseConfigWithCCW() throws JsonParseException, JsonMappingException, IOException {
GetScatterplotCommand.PlotterConfig config = ParsingUtilities.mapper.readValue(configJsonWithCCW, GetScatterplotCommand.PlotterConfig.class);
Assert.assertEquals(ScatterplotFacet.ROTATE_CCW, config.rotation);
}
} }