📄 fastscatterplot.java
字号:
);
Rectangle2D dataArea = space.shrink(area, null);
if (info != null) {
info.setDataArea(dataArea);
}
// draw the plot background and axes...
drawBackground(g2, dataArea);
AxisState domainAxisState = null;
AxisState rangeAxisState = null;
if (this.domainAxis != null) {
domainAxisState = this.domainAxis.draw(
g2, dataArea.getMaxY(), area, dataArea,
RectangleEdge.BOTTOM, info
);
}
if (this.rangeAxis != null) {
rangeAxisState = this.rangeAxis.draw(
g2, dataArea.getMinX(), area, dataArea,
RectangleEdge.LEFT, info
);
}
drawDomainGridlines(g2, dataArea, domainAxisState.getTicks());
drawRangeGridlines(g2, dataArea, rangeAxisState.getTicks());
Shape originalClip = g2.getClip();
Composite originalComposite = g2.getComposite();
g2.clip(dataArea);
g2.setComposite(
AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, getForegroundAlpha()
)
);
render(g2, dataArea, info, null);
g2.setClip(originalClip);
g2.setComposite(originalComposite);
drawOutline(g2, dataArea);
}
/**
* Draws a representation of the data within the dataArea region. The
* <code>info</code> and <code>crosshairState</code> arguments may be
* <code>null</code>.
*
* @param g2 the graphics device.
* @param dataArea the region in which the data is to be drawn.
* @param info an optional object for collection dimension information.
* @param crosshairState collects crosshair information (<code>null</code>
* permitted).
*/
public void render(Graphics2D g2, Rectangle2D dataArea,
PlotRenderingInfo info, CrosshairState crosshairState) {
//long start = System.currentTimeMillis();
//System.out.println("Start: " + start);
g2.setPaint(this.paint);
// if the axes use a linear scale, you can uncomment the code below and
// switch to the alternative transX/transY calculation inside the loop
// that follows - it is a little bit faster then.
//
// int xx = (int) dataArea.getMinX();
// int ww = (int) dataArea.getWidth();
// int yy = (int) dataArea.getMaxY();
// int hh = (int) dataArea.getHeight();
// double domainMin = this.domainAxis.getLowerBound();
// double domainLength = this.domainAxis.getUpperBound() - domainMin;
// double rangeMin = this.rangeAxis.getLowerBound();
// double rangeLength = this.rangeAxis.getUpperBound() - rangeMin;
if (this.data != null) {
for (int i = 0; i < this.data[0].length; i++) {
float x = this.data[0][i];
float y = this.data[1][i];
//int transX = (int) (xx + ww * (x - domainMin) / domainLength);
//int transY = (int) (yy - hh * (y - rangeMin) / rangeLength);
int transX = (int) this.domainAxis.valueToJava2D(
x, dataArea, RectangleEdge.BOTTOM
);
int transY = (int) this.rangeAxis.valueToJava2D(
y, dataArea, RectangleEdge.LEFT
);
g2.fillRect(transX, transY, 1, 1);
}
}
//long finish = System.currentTimeMillis();
//System.out.println("Finish: " + finish);
//System.out.println("Time: " + (finish - start));
}
/**
* Draws the gridlines for the plot, if they are visible.
*
* @param g2 the graphics device.
* @param dataArea the data area.
* @param ticks the ticks.
*/
protected void drawDomainGridlines(Graphics2D g2, Rectangle2D dataArea,
List ticks) {
// draw the domain grid lines, if any...
if (isDomainGridlinesVisible()) {
Stroke gridStroke = getDomainGridlineStroke();
Paint gridPaint = getDomainGridlinePaint();
if ((gridStroke != null) && (gridPaint != null)) {
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
ValueTick tick = (ValueTick) iterator.next();
double v = this.domainAxis.valueToJava2D(
tick.getValue(), dataArea, RectangleEdge.BOTTOM
);
Line2D line = new Line2D.Double(
v, dataArea.getMinY(), v, dataArea.getMaxY()
);
g2.setPaint(gridPaint);
g2.setStroke(gridStroke);
g2.draw(line);
}
}
}
}
/**
* Draws the gridlines for the plot, if they are visible.
*
* @param g2 the graphics device.
* @param dataArea the data area.
* @param ticks the ticks.
*/
protected void drawRangeGridlines(Graphics2D g2, Rectangle2D dataArea,
List ticks) {
// draw the range grid lines, if any...
if (isRangeGridlinesVisible()) {
Stroke gridStroke = getRangeGridlineStroke();
Paint gridPaint = getRangeGridlinePaint();
if ((gridStroke != null) && (gridPaint != null)) {
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
ValueTick tick = (ValueTick) iterator.next();
double v = this.rangeAxis.valueToJava2D(
tick.getValue(), dataArea, RectangleEdge.LEFT
);
Line2D line = new Line2D.Double(
dataArea.getMinX(), v, dataArea.getMaxX(), v
);
g2.setPaint(gridPaint);
g2.setStroke(gridStroke);
g2.draw(line);
}
}
}
}
/**
* Returns the range of data values to be plotted along the axis.
*
* @param axis the axis.
*
* @return The range.
*/
public Range getDataRange(ValueAxis axis) {
Range result = null;
if (axis == this.domainAxis) {
result = this.xDataRange;
}
else if (axis == this.rangeAxis) {
result = this.yDataRange;
}
return result;
}
/**
* Calculates the X data range.
*
* @param data the data.
*
* @return The range.
*/
private Range calculateXDataRange(float[][] data) {
Range result = null;
if (data != null) {
float lowest = Float.POSITIVE_INFINITY;
float highest = Float.NEGATIVE_INFINITY;
for (int i = 0; i < data[0].length; i++) {
float v = data[0][i];
if (v < lowest) {
lowest = v;
}
if (v > highest) {
highest = v;
}
}
if (lowest <= highest) {
result = new Range(lowest, highest);
}
}
return result;
}
/**
* Calculates the Y data range.
*
* @param data the data.
*
* @return The range.
*/
private Range calculateYDataRange(float[][] data) {
Range result = null;
if (data != null) {
float lowest = Float.POSITIVE_INFINITY;
float highest = Float.NEGATIVE_INFINITY;
for (int i = 0; i < data[0].length; i++) {
float v = data[1][i];
if (v < lowest) {
lowest = v;
}
if (v > highest) {
highest = v;
}
}
if (lowest <= highest) {
result = new Range(lowest, highest);
}
}
return result;
}
/**
* Multiplies the range on the domain axis/axes by the specified factor.
*
* @param factor the zoom factor.
* @param info the plot rendering info.
* @param source the source point.
*/
public void zoomDomainAxes(double factor, PlotRenderingInfo info,
Point2D source) {
this.domainAxis.resizeRange(factor);
}
/**
* Zooms in on the domain axes.
*
* @param lowerPercent the new lower bound as a percentage of the current
* range.
* @param upperPercent the new upper bound as a percentage of the current
* range.
* @param info the plot rendering info.
* @param source the source point.
*/
public void zoomDomainAxes(double lowerPercent, double upperPercent,
PlotRenderingInfo info, Point2D source) {
this.domainAxis.zoomRange(lowerPercent, upperPercent);
}
/**
* Multiplies the range on the range axis/axes by the specified factor.
*
* @param factor the zoom factor.
* @param info the plot rendering info.
* @param source the source point.
*/
public void zoomRangeAxes(double factor,
PlotRenderingInfo info, Point2D source) {
this.rangeAxis.resizeRange(factor);
}
/**
* Zooms in on the range axes.
*
* @param lowerPercent the new lower bound as a percentage of the current
* range.
* @param upperPercent the new upper bound as a percentage of the current
* range.
* @param info the plot rendering info.
* @param source the source point.
*/
public void zoomRangeAxes(double lowerPercent, double upperPercent,
PlotRenderingInfo info, Point2D source) {
this.rangeAxis.zoomRange(lowerPercent, upperPercent);
}
/**
* Returns <code>true</code>.
*
* @return A boolean.
*/
public boolean isDomainZoomable() {
return true;
}
/**
* Returns <code>true</code>.
*
* @return A boolean.
*/
public boolean isRangeZoomable() {
return true;
}
/**
* Tests an object for equality with this instance.
*
* @param obj the object (<code>null</code> permitted).
*
* @return A boolean.
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof FastScatterPlot)) {
return false;
}
FastScatterPlot that = (FastScatterPlot) obj;
if (!ArrayUtilities.equal(this.data, that.data)) {
return false;
}
if (!ObjectUtilities.equal(this.domainAxis, that.domainAxis)) {
return false;
}
if (!ObjectUtilities.equal(this.rangeAxis, that.rangeAxis)) {
return false;
}
if (!PaintUtilities.equal(this.paint, that.paint)) {
return false;
}
if (this.domainGridlinesVisible != that.domainGridlinesVisible) {
return false;
}
if (!PaintUtilities.equal(this.domainGridlinePaint,
that.domainGridlinePaint)) {
return false;
}
if (!ObjectUtilities.equal(this.domainGridlineStroke,
that.domainGridlineStroke)) {
return false;
}
if (!this.rangeGridlinesVisible == that.rangeGridlinesVisible) {
return false;
}
if (!PaintUtilities.equal(this.rangeGridlinePaint,
that.rangeGridlinePaint)) {
return false;
}
if (!ObjectUtilities.equal(this.rangeGridlineStroke,
that.rangeGridlineStroke)) {
return false;
}
return true;
}
/**
* Returns a clone of the plot.
*
* @return A clone.
*
* @throws CloneNotSupportedException if some component of the plot does
* not support cloning.
*/
public Object clone() throws CloneNotSupportedException {
FastScatterPlot clone = (FastScatterPlot) super.clone();
if (this.data != null) {
clone.data = ArrayUtilities.clone(this.data);
}
if (this.domainAxis != null) {
clone.domainAxis = (ValueAxis) this.domainAxis.clone();
clone.domainAxis.setPlot(clone);
clone.domainAxis.addChangeListener(clone);
}
if (this.rangeAxis != null) {
clone.rangeAxis = (ValueAxis) this.rangeAxis.clone();
clone.rangeAxis.setPlot(clone);
clone.rangeAxis.addChangeListener(clone);
}
return clone;
}
/**
* Provides serialization support.
*
* @param stream the output stream.
*
* @throws IOException if there is an I/O error.
*/
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.paint, stream);
SerialUtilities.writeStroke(this.domainGridlineStroke, stream);
SerialUtilities.writePaint(this.domainGridlinePaint, stream);
SerialUtilities.writeStroke(this.rangeGridlineStroke, stream);
SerialUtilities.writePaint(this.rangeGridlinePaint, stream);
}
/**
* Provides serialization support.
*
* @param stream the input stream.
*
* @throws IOException if there is an I/O error.
* @throws ClassNotFoundException if there is a classpath problem.
*/
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.paint = SerialUtilities.readPaint(stream);
this.domainGridlineStroke = SerialUtilities.readStroke(stream);
this.domainGridlinePaint = SerialUtilities.readPaint(stream);
this.rangeGridlineStroke = SerialUtilities.readStroke(stream);
this.rangeGridlinePaint = SerialUtilities.readPaint(stream);
if (this.domainAxis != null) {
this.domainAxis.addChangeListener(this);
}
if (this.rangeAxis != null) {
this.rangeAxis.addChangeListener(this);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -