📄 plotter.java
字号:
// minColor = Math.min(minColor, color);
// maxColor = Math.max(maxColor, color);
// }
// } else {
// y = Double.parseDouble(row[column].toString());
// }
PlotterPoint currentPoint = new PlotterPoint(statRow.getId(), x, y, color);
if (currentPoint.isIn(drawMinX, drawMaxX, drawMinY, drawMaxY)) {
points.add(currentPoint);
minX = Math.min(x, minX);
maxX = Math.max(x, maxX);
minY = Math.min(y, minY);
maxY = Math.max(y, maxY);
}
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Not a numerical data column: "+column);
}
}
}
plots.add(points);
}
}
}
if (!Double.isInfinite(drawMinX)) minX = drawMinX;
if (!Double.isInfinite(drawMaxX)) minX = drawMaxX;
if (!Double.isInfinite(drawMinY)) minX = drawMinX;
if (!Double.isInfinite(drawMaxY)) minX = drawMinX;
if (statistics.getNumberOfRows() == 0) {
minX = minY = 0;
maxX = maxY = 1;
}
if (minX == maxX) {
minX -= 0.5;
maxX += 0.5;
}
if (minY == maxY) {
minY -= 0.5;
maxY += 0.5;
}
xTicSize = getTicSize(minX, maxX);
yTicSize = getTicSize(minY, maxY);
minX = Math.floor(minX / xTicSize) * xTicSize;
maxX = Math.ceil(maxX / xTicSize) * xTicSize;
minY = Math.floor(minY / yTicSize) * yTicSize;
maxY = Math.ceil(maxY / yTicSize) * yTicSize;
}
public void set3DPlot(boolean plot3D) {
this.plot3D = plot3D;
}
/** Sets the mouse position in the shown data space. Returns true, if a new tool tip should be drawn. */
public boolean setMousePosInDataSpace(int x, int y) {
PlotterPoint point = getPlotterPointForPos(x, y);
boolean repaint = false;
if (point != null) {
String id = point.getId();
if (id != null) {
repaint = !id.equals(currentToolTip);
setToolTip(id, point.getX(), point.getY());
} else {
repaint = currentToolTip != null;
setToolTip(null, 0.0d, 0.0d);
}
} else {
repaint = currentToolTip != null;
setToolTip(null, 0.0d, 0.0d);
}
return repaint;
}
public PlotterPoint getPlotterPointForPos(int x, int y) {
Iterator i = plots.iterator();
while (i.hasNext()) {
SortedSet plot = (SortedSet)i.next();
Iterator p = plot.iterator();
while (p.hasNext()) {
PlotterPoint current = (PlotterPoint)p.next();
if (current.contains(x, y)) return current;
}
}
return null;
}
public void setDragBounds(int dragX, int dragY, int dragWidth, int dragHeight) {
this.dragX = dragX;
this.dragY = dragY;
this.dragWidth = dragWidth;
this.dragHeight = dragHeight;
}
private void setToolTip(String toolTip, double x, double y) {
this.currentToolTip = toolTip;
this.toolTipX = x;
this.toolTipY = y;
}
private double getTicSize(double min, double max) {
double delta = (max - min) / 5;
double e = Math.floor(Math.log(delta) / Math.log(10));
double factor = Math.pow(10, e);
for (int i = TICS.length-1; i >= 0 ; i--) {
if (TICS[i]*factor <= delta) return TICS[i] * factor;
}
return factor;
}
private void drawPoints(Graphics2D g, double dx, double dy, double sx, double sy) {
if (plots.size() == 0) return;
int c = 0;
Iterator p = plots.iterator();
while (p.hasNext()) {
Plot plot = (Plot)p.next();
if (plot.size() > 0) {
if (plot3D)
plot.getLineStyle().set(g);
GeneralPath path = new GeneralPath();
Iterator i = plot.iterator();
boolean first = true;
while (i.hasNext()) {
PlotterPoint plotterPoint = (PlotterPoint)i.next();
float gSpaceX = (float)((plotterPoint.getX()+dx)*sx);
float gSpaceY = (float)((plotterPoint.getY()+dy)*sy);
if (first || !plot3D) path.moveTo(gSpaceX, gSpaceY);
else path.lineTo(gSpaceX, gSpaceY);
java.awt.geom.RectangularShape circle = new java.awt.geom.Ellipse2D.Double(gSpaceX - 2, gSpaceY - 2, 5, 5);
if (!plot3D) {
double scaledColor = (double)(plotterPoint.getColor() - minColor) / (double)(maxColor - minColor);
Color pointColor = new Color(Color.HSBtoRGB((float)(0.7*scaledColor), 1.0f, 1.0f));
g.setColor(pointColor);
}
g.fill(circle);
first = false;
}
g.draw(path);
c = (c+1)%LINE_STYLES.length;
}
}
}
private void drawToolTip(Graphics2D g, double dx, double dy, double sx, double sy) {
if (currentToolTip != null) {
g.setFont(LABEL_FONT);
Rectangle2D stringBounds = LABEL_FONT.getStringBounds(currentToolTip, g.getFontRenderContext());
g.setColor(new Color(170, 150, 240, 210));
Rectangle2D bg = new Rectangle2D.Double((toolTipX+dx)*sx - stringBounds.getWidth()/2 - 4,
(toolTipY+dy)*sy + 3,
stringBounds.getWidth() + 5,
Math.abs(stringBounds.getHeight()) + 3);
g.fill(bg);
g.setColor(Color.black);
g.draw(bg);
g.drawString(currentToolTip,
(float)((toolTipX+dx)*sx - stringBounds.getWidth()/2) - 2,
(float)((toolTipY+dy)*sy) + 6); // + stringBounds.getHeight()));
}
}
private void drawGrid(Graphics2D g, double dx, double dy, double sx, double sy) {
DecimalFormat format = new DecimalFormat("0.00E0");
g.setFont(LABEL_FONT);
g.setStroke(new BasicStroke(1));
for (int i = 0; i < 12; i++) {
double x = i*xTicSize + minX;
double y = i*yTicSize + minY;
g.setColor(GRID_COLOR);
g.draw(new Line2D.Double((x+dx) *sx, (minY+dy)*sy, (x+dx) *sx, (maxY+dy)*sy));
g.draw(new Line2D.Double((minX+dx)*sx, (y+dy) *sy, (maxX+dx)*sx, (y+dy) *sy));
g.setColor(Color.black);
String label = format.format(y)+" ";
Rectangle2D stringBounds = LABEL_FONT.getStringBounds(label, g.getFontRenderContext());
g.drawString(label,
(float)((minX+dx)*sx - stringBounds.getWidth()),
(float)((y+dy)*sy - stringBounds.getHeight()/2 - stringBounds.getY()));
label = format.format(x);
stringBounds = LABEL_FONT.getStringBounds(label, g.getFontRenderContext());
g.drawString(label,
(float)((x+dx)*sx - stringBounds.getWidth()/2),
(float)((minY+dy)*sy + stringBounds.getHeight()));
}
}
private void draw(Graphics2D g, int pixWidth, int pixHeight) {
double sx = ((double)pixWidth-LABEL_MARGIN_Y) / (maxX-minX);
double sy = ((double)pixHeight-LABEL_MARGIN_X) / (maxY-minY);
Graphics2D coordinateSpace = (Graphics2D)g.create();
coordinateSpace.translate(LABEL_MARGIN_Y, LABEL_MARGIN_X);
if (Double.isNaN(sx) || Double.isNaN(sy)) {
coordinateSpace.scale(1,-1);
coordinateSpace.drawString("No data points available (yet).", 0, -20);
coordinateSpace.drawString("Zooming out with a right click might help.", 0, 0);
} else {
transform.translate(LABEL_MARGIN_Y, LABEL_MARGIN_X);
transform.scale(sx, sy);
transform.translate(-minX, -minY);
drawGrid(coordinateSpace, -minX, -minY, sx, sy);
drawPoints(coordinateSpace, -minX, -minY, sx, sy);
drawToolTip(coordinateSpace, -minX, -minY, sx, sy);
}
coordinateSpace.dispose();
}
private void drawDragRectangle(Graphics2D g) {
if ((dragX != -1) && (dragY != -1) && (dragWidth != -1) && (dragHeight != -1)) {
g.setColor(Color.gray);
Rectangle2D dragBounds = new Rectangle2D.Double(dragX, dragY, dragWidth, dragHeight);
g.draw(dragBounds);
}
}
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
if ((yAxis == -1) || (!plot3D)) {
paint2DPlots(graphics);
} else {
createGNUPlot(graphics);
if (cachedImage != null)
graphics.drawImage(cachedImage, 0, 0, null);
}
}
private int[] getZ() {
int count = 0;
for (int i = 0; i < columns.length; i++)
if (columns[i]) count++;
if (count == 0) {
return null;
} else {
int[] z = new int[count];
int j = 0;
for (int i = 0; i < columns.length; i++) {
if (columns[i]) z[j++] = i;
}
return z;
}
}
private void createGNUPlot(Graphics graphics) {
if (hasChanged) {
int[] z = getZ();
if (z != null) {
try {
cachedImage = statistics.createGNUPlot(xAxis, yAxis, z,
gnuPlotDialog.getLineType(),
gnuPlotDialog.getGNUPlotCommands()+"\n"+
"set view "+rotX+","+rotZ+"");
hasChanged = false;
} catch (Exception e) {
SwingTools.showSimpleErrorMessage("Error executing gnuplot", e);
}
}
}
}
private void paint2DPlots(Graphics graphics) {
Graphics2D g = (Graphics2D)graphics;
int pixWidth = getWidth() - 2*MARGIN;
int pixHeight = getHeight() - 2*MARGIN;
Graphics2D scaled = (Graphics2D)g.create();
scaled.translate(MARGIN, MARGIN);
scaled.translate(0, pixHeight+1);
prepareData();
if (plots.size() == 0) {
scaled.drawString("No plots selected.", 0, 0);
} else {
scaled.scale(1,-1);
g.setColor(Color.black);
transform = new AffineTransform();
transform.translate(MARGIN, MARGIN);
transform.translate(0, pixHeight+1);
transform.scale(1,-1);
draw(scaled, pixWidth, pixHeight);
}
scaled.dispose();
String xAxisLabel = statistics.getColumnName(xAxis);
Rectangle2D stringBounds = LABEL_FONT.getStringBounds(xAxisLabel, g.getFontRenderContext());
g.drawString(xAxisLabel,
MARGIN + (int)(pixWidth/2-stringBounds.getWidth()/2),
MARGIN + (int)(pixHeight + stringBounds.getY())+3);
drawDragRectangle(g);
}
public AffineTransform getTransform() {
return transform;
}
public void statisticsUpdated(Statistics source) {
hasChanged = true;
repaint();
}
public void setXAxis(int xAxis) {
if (this.xAxis != xAxis) {
this.hasChanged = true;
this.xAxis = xAxis;
}
}
public void setYAxis(int yAxis) {
if (this.yAxis != yAxis) {
this.hasChanged = true;
this.yAxis = yAxis;
}
}
public void setDrawAmount(int amount) {
this.drawAmount = amount;
}
public void plotColumn(int index, boolean plot) {
if (this.columns[index] != plot) {
this.hasChanged = true;
columns[index] = plot;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -