📄 thermometerplot.java
字号:
COLUMN_DIAMETER,
COLUMN_DIAMETER);
Area outerThermometer = new Area(outerBulb);
Area tempArea = new Area(outerStem);
outerThermometer.add(tempArea);
innerBulb.setFrame(midX - BULB_RADIUS + GAP_RADIUS,
stemBottom + GAP_RADIUS,
BULB_DIAMETER - GAP_DIAMETER,
BULB_DIAMETER - GAP_DIAMETER);
innerStem.setRoundRect(midX - COLUMN_RADIUS + GAP_RADIUS,
plotArea.getMinY() + GAP_RADIUS,
COLUMN_DIAMETER - GAP_DIAMETER,
stemBottom + BULB_DIAMETER - GAP_DIAMETER - stemTop,
COLUMN_DIAMETER - GAP_DIAMETER,
COLUMN_DIAMETER - GAP_DIAMETER);
Area innerThermometer = new Area(innerBulb);
tempArea = new Area(innerStem);
innerThermometer.add(tempArea);
if ((this.dataset != null) && (this.dataset.getValue() != null)) {
double current = this.dataset.getValue().doubleValue();
double ds = rangeAxis.translateValueToJava2D(current, dataArea, RectangleEdge.LEFT);
int i = COLUMN_DIAMETER - GAP_DIAMETER; // already calculated
int j = COLUMN_RADIUS - GAP_RADIUS; // already calculated
int l = (int) (i / 2);
int k = (int) Math.round(ds);
if (k < (GAP_RADIUS + plotArea.getMinY())) {
k = (int) (GAP_RADIUS + plotArea.getMinY());
l = BULB_RADIUS;
}
Area mercury = new Area(innerBulb);
if (k < (stemBottom + BULB_RADIUS)) {
mercuryStem.setRoundRect(midX - j, k, i, (stemBottom + BULB_RADIUS) - k, l, l);
tempArea = new Area(mercuryStem);
mercury.add(tempArea);
}
g2.setPaint(getCurrentPaint());
g2.fill(mercury);
// draw the axis...
int drawWidth = AXIS_GAP;
if (showValueLines) {
drawWidth += COLUMN_DIAMETER;
}
Rectangle2D drawArea = new Rectangle2D.Double(midX - COLUMN_RADIUS - AXIS_GAP,
stemTop,
drawWidth,
(stemBottom - stemTop + 1));
double cursor = 0.0;
cursor = this.rangeAxis.draw(g2, cursor, plotArea, drawArea, RectangleEdge.LEFT);
// draw range indicators...
if (this.subrangeIndicatorsVisible) {
g2.setStroke(this.subrangeIndicatorStroke);
Range range = rangeAxis.getRange();
// draw start of normal range
double value = this.subrangeInfo[NORMAL][RANGE_LOW];
if (range.contains(value)) {
double x = midX + COLUMN_RADIUS + 2;
double y = rangeAxis.translateValueToJava2D(value, dataArea,
RectangleEdge.LEFT);
Line2D line = new Line2D.Double(x, y, x + 10, y);
g2.setPaint(subrangePaint[NORMAL]);
g2.draw(line);
}
// draw start of warning range
value = this.subrangeInfo[WARNING][RANGE_LOW];
if (range.contains(value)) {
double x = midX + COLUMN_RADIUS + 2;
double y = rangeAxis.translateValueToJava2D(value, dataArea,
RectangleEdge.LEFT);
Line2D line = new Line2D.Double(x, y, x + 10, y);
g2.setPaint(subrangePaint[WARNING]);
g2.draw(line);
}
// draw start of critical range
value = this.subrangeInfo[CRITICAL][RANGE_LOW];
if (range.contains(value)) {
double x = midX + COLUMN_RADIUS + 2;
double y = rangeAxis.translateValueToJava2D(value, dataArea,
RectangleEdge.LEFT);
Line2D line = new Line2D.Double(x, y, x + 10, y);
g2.setPaint(subrangePaint[CRITICAL]);
g2.draw(line);
}
}
// draw text value on screen
g2.setFont(this.valueFont);
g2.setPaint(this.valuePaint);
metrics = g2.getFontMetrics();
switch (valueLocation) {
case RIGHT:
g2.drawString(valueFormat.format(current),
midX + COLUMN_RADIUS + GAP_RADIUS, midY);
break;
case BULB:
temp = valueFormat.format(current);
i = (int) (metrics.stringWidth(temp) / 2);
g2.drawString(temp, midX - i, stemBottom + BULB_RADIUS + GAP_RADIUS);
break;
default:
}
}
g2.setPaint(thermometerPaint);
g2.setFont(valueFont);
// draw units indicator
metrics = g2.getFontMetrics();
int tickX1 = midX - COLUMN_RADIUS - GAP_DIAMETER - metrics.stringWidth(UNITS[units]);
if (tickX1 > plotArea.getMinX()) {
g2.drawString(UNITS[units], tickX1, (int) (plotArea.getMinY() + 20));
}
// draw thermometer outline
g2.setStroke(thermometerStroke);
g2.draw(outerThermometer);
g2.draw(innerThermometer);
drawOutline(g2, plotArea);
}
/**
* A zoom method that does nothing.
* <p>
* Plots are required to support the zoom operation. In the case of a
* thermometer chart, it doesn't make sense to zoom in or out, so the
* method is empty.
*
* @param percent the zoom percentage.
*/
public void zoom(double percent) { }
/**
* Returns a short string describing the type of plot.
*
* @return a short string describing the type of plot.
*/
public String getPlotType() {
return "Thermometer Plot";
}
/**
* Checks to see if a new value means the axis range needs adjusting.
*
* @param event the dataset change event.
*/
public void datasetChanged(DatasetChangeEvent event) {
Number vn = this.dataset.getValue();
if (vn != null) {
double value = vn.doubleValue();
if (inSubrange(NORMAL, value)) {
this.subrange = NORMAL;
}
else if (inSubrange(WARNING, value)) {
this.subrange = WARNING;
}
else if (inSubrange(CRITICAL, value)) {
this.subrange = CRITICAL;
}
else {
this.subrange = -1;
}
setAxisRange();
}
super.datasetChanged(event);
}
/**
* Returns the minimum value in either the domain or the range, whichever
* is displayed against the vertical axis for the particular type of plot
* implementing this interface.
*
* @return the minimum value in either the domain or the range.
*/
public Number getMinimumVerticalDataValue() {
return new Double(this.lowerBound);
}
/**
* Returns the maximum value in either the domain or the range, whichever
* is displayed against the vertical axis for the particular type of plot
* implementing this interface.
*
* @return the maximum value in either the domain or the range
*/
public Number getMaximumVerticalDataValue() {
return new Double(this.upperBound);
}
/**
* Returns the data range.
*
* @param axis the axis.
*
* @return The range of data displayed.
*/
public Range getDataRange(ValueAxis axis) {
return new Range(this.lowerBound, this.upperBound);
}
/**
* Sets the axis range to the current values in the rangeInfo array.
*/
protected void setAxisRange() {
if ((this.subrange >= 0) && (this.followDataInSubranges)) {
rangeAxis.setRange(new Range(subrangeInfo[subrange][DISPLAY_LOW],
subrangeInfo[subrange][DISPLAY_HIGH]));
}
else {
rangeAxis.setRange(this.lowerBound, this.upperBound);
}
}
/**
* Returns null, since the thermometer plot won't require a legend.
*
* @return null.
*
* @deprecated use getLegendItems().
*/
public List getLegendItemLabels() {
return null;
}
/**
* Returns the legend items for the plot.
*
* @return null.
*/
public LegendItemCollection getLegendItems() {
return null;
}
/**
* Returns the vertical value axis.
* <p>
* This is required by the VerticalValuePlot interface, but not used in this class.
*
* @return the vertical value axis.
*/
public ValueAxis getVerticalValueAxis() {
return this.rangeAxis;
}
/**
* Determine whether a number is valid and finite.
*
* @param d the number to be tested.
*
* @return true if the number is valid and finite, and false otherwise.
*/
protected static boolean isValidNumber(double d) {
return (!(Double.isNaN(d) || Double.isInfinite(d)));
}
/**
* Returns true if the value is in the specified range, and false otherwise.
*
* @param subrange the subrange.
* @param value the value to check.
*
* @return true or false.
*/
private boolean inSubrange(int subrange, double value) {
return (value > subrangeInfo[subrange][RANGE_LOW]
&& value <= subrangeInfo[subrange][RANGE_HIGH]);
}
/**
* Returns the mercury paint corresponding to the current data value.
*
* @return the paint.
*/
private Paint getCurrentPaint() {
Paint result = this.mercuryPaint;
if (this.useSubrangePaint) {
double value = this.dataset.getValue().doubleValue();
if (inSubrange(NORMAL, value)) {
result = this.subrangePaint[NORMAL];
}
else if (inSubrange(WARNING, value)) {
result = this.subrangePaint[WARNING];
}
else if (inSubrange(CRITICAL, value)) {
result = this.subrangePaint[CRITICAL];
}
}
return result;
}
/**
* Tests this plot for equality with another object.
*
* @param obj the object.
*
* @return <code>true</code> or <code>false</code>.
*/
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj instanceof ThermometerPlot) {
ThermometerPlot p = (ThermometerPlot) obj;
if (super.equals(obj)) {
boolean b0 = ObjectUtils.equalOrBothNull(this.dataset, p.dataset);
boolean b1 = ObjectUtils.equalOrBothNull(this.rangeAxis, p.rangeAxis);
boolean b2 = (this.lowerBound == p.lowerBound);
boolean b3 = (this.upperBound == p.upperBound);
boolean b4 = ObjectUtils.equalOrBothNull(this.padding, p.padding);
boolean b5 = ObjectUtils.equalOrBothNull(this.thermometerStroke,
p.thermometerStroke);
boolean b6 = ObjectUtils.equalOrBothNull(this.thermometerPaint,
p.thermometerPaint);
boolean b7 = (this.units == p.units);
boolean b8 = (this.valueLocation == p.valueLocation);
boolean b9 = ObjectUtils.equalOrBothNull(this.valueFont, p.valueFont);
boolean b10 = ObjectUtils.equalOrBothNull(this.valuePaint, p.valuePaint);
boolean b11 = ObjectUtils.equalOrBothNull(this.valueFormat, p.valueFormat);
boolean b12 = ObjectUtils.equalOrBothNull(this.mercuryPaint, p.mercuryPaint);
boolean b13 = (this.showValueLines == p.showValueLines);
boolean b14 = (this.subrange == p.subrange);
boolean b15 = true; //Arrays.equals(this.subRangeInfo, p.subRangeInfo);
boolean b16 = (this.followDataInSubranges == p.followDataInSubranges);
boolean b17 = (this.useSubrangePaint == p.useSubrangePaint);
return b0 && b1 && b2 && b3 && b4 && b5 && b6 && b7 && b8 && b9
&& b10 && b11 && b12 && b13 && b14 && b15 && b16 && b17;
}
}
return false;
}
/**
* 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.writeStroke(this.thermometerStroke, stream);
SerialUtilities.writePaint(this.thermometerPaint, stream);
SerialUtilities.writePaint(this.valuePaint, stream);
SerialUtilities.writePaint(this.mercuryPaint, stream);
SerialUtilities.writeStroke(this.subrangeIndicatorStroke, stream);
SerialUtilities.writeStroke(this.rangeIndicatorStroke, 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.thermometerStroke = SerialUtilities.readStroke(stream);
this.thermometerPaint = SerialUtilities.readPaint(stream);
this.valuePaint = SerialUtilities.readPaint(stream);
this.mercuryPaint = SerialUtilities.readPaint(stream);
this.subrangeIndicatorStroke = SerialUtilities.readStroke(stream);
this.rangeIndicatorStroke = SerialUtilities.readStroke(stream);
if (this.rangeAxis != null) {
this.rangeAxis.addChangeListener(this);
}
}
/**
* Multiplies the range on the horizontal axis/axes by the specified factor.
*
* @param factor the zoom factor.
*/
public void zoomHorizontalAxes(double factor) {
// do nothing
}
/**
* Multiplies the range on the vertical axis/axes by the specified factor.
*
* @param factor the zoom factor.
*/
public void zoomVerticalAxes(double factor) {
// zoom the range axis
}
/**
* Zooms the horizontal axes.
*
* @param lowerPercent the lower percent.
* @param upperPercent the upper percent.
*/
public void zoomHorizontalAxes(double lowerPercent, double upperPercent) {
// zoom the domain axis
}
/**
* Zooms the vertical axes.
*
* @param lowerPercent the lower percent.
* @param upperPercent the upper percent.
*/
public void zoomVerticalAxes(double lowerPercent, double upperPercent) {
// zoom the domain axis
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -