📄 contourplot.java
字号:
if (this.annotations == null) { this.annotations = new java.util.ArrayList(); } this.annotations.add(annotation); notifyListeners(new PlotChangeEvent(this)); } /** * Clears all the annotations. */ public void clearAnnotations() { if (this.annotations != null) { this.annotations.clear(); notifyListeners(new PlotChangeEvent(this)); } } /** * Checks the compatibility of a domain axis, returning true if the axis is * compatible with the plot, and false otherwise. * * @param axis The proposed axis. * * @return <code>true</code> if the axis is compatible with the plot. */ public boolean isCompatibleDomainAxis(ValueAxis axis) { return true; } /** * Draws the plot on a Java 2D graphics device (such as the screen or a printer). * <P> * The optional <code>info</code> argument collects information about the rendering of * the plot (dimensions, tooltip information etc). Just pass in <code>null</code> if * you do not need this information. * * @param g2 the graphics device. * @param plotArea the area within which the plot (including axis labels) should be drawn. * @param parentState the state from the parent plot, if there is one. * @param info collects chart drawing information (<code>null</code> permitted). */ public void draw(Graphics2D g2, Rectangle2D plotArea, PlotState parentState, PlotRenderingInfo info) { // if the plot area is too small, just return... boolean b1 = (plotArea.getWidth() <= MINIMUM_WIDTH_TO_DRAW); boolean b2 = (plotArea.getHeight() <= MINIMUM_HEIGHT_TO_DRAW); if (b1 || b2) { return; } // record the plot area... if (info != null) { info.setPlotArea(plotArea); } // adjust the drawing area for plot insets (if any)... Insets insets = getInsets(); if (insets != null) { plotArea.setRect(plotArea.getX() + insets.left, plotArea.getY() + insets.top, plotArea.getWidth() - insets.left - insets.right, plotArea.getHeight() - insets.top - insets.bottom); } AxisSpace space = new AxisSpace(); space = this.domainAxis.reserveSpace(g2, this, plotArea, RectangleEdge.BOTTOM, space); space = this.rangeAxis.reserveSpace(g2, this, plotArea, RectangleEdge.LEFT, space); Rectangle2D estimatedDataArea = space.shrink(plotArea, null); AxisSpace space2 = new AxisSpace(); space2 = this.colorBar.reserveSpace(g2, this, plotArea, estimatedDataArea, this.colorBarLocation, space2); Rectangle2D adjustedPlotArea = space2.shrink(plotArea, null); Rectangle2D dataArea = space.shrink(adjustedPlotArea, null); Rectangle2D colorBarArea = space2.reserved(plotArea, this.colorBarLocation); // additional dataArea modifications if (getDataAreaRatio() != 0.0) { //check whether modification is double ratio = getDataAreaRatio(); Rectangle2D tmpDataArea = (Rectangle2D) dataArea.clone(); double h = tmpDataArea.getHeight(); double w = tmpDataArea.getWidth(); if (ratio > 0) { // ratio represents pixels if (w * ratio <= h) { h = ratio * w; } else { w = h / ratio; } } else { // ratio represents axis units ratio *= -1.0; double xLength = getDomainAxis().getRange().getLength(); double yLength = getRangeAxis().getRange().getLength(); double unitRatio = yLength / xLength; ratio = unitRatio * ratio; if (w * ratio <= h) { h = ratio * w; } else { w = h / ratio; } } dataArea.setRect(tmpDataArea.getX() + tmpDataArea.getWidth() / 2 - w / 2, tmpDataArea.getY(), w, h); } if (info != null) { info.setDataArea(dataArea); } CrosshairState crosshairState = new CrosshairState(); crosshairState.setCrosshairDistance(Double.POSITIVE_INFINITY); // draw the plot background... drawBackground(g2, dataArea); double cursor = dataArea.getMaxY(); if (this.domainAxis != null) { this.domainAxis.draw( g2, cursor, adjustedPlotArea, dataArea, RectangleEdge.BOTTOM, info ); } if (this.rangeAxis != null) { cursor = dataArea.getMinX(); this.rangeAxis.draw( g2, cursor, adjustedPlotArea, dataArea, RectangleEdge.LEFT, info ); } if (this.colorBar != null) { cursor = 0.0; cursor = this.colorBar.draw(g2, cursor, adjustedPlotArea, dataArea, colorBarArea, this.colorBarLocation); } Shape originalClip = g2.getClip(); Composite originalComposite = g2.getComposite(); g2.clip(dataArea); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getForegroundAlpha())); render(g2, dataArea, info, crosshairState); if (this.domainMarkers != null) { Iterator iterator = this.domainMarkers.iterator(); while (iterator.hasNext()) { Marker marker = (Marker) iterator.next(); drawDomainMarker(g2, this, getDomainAxis(), marker, dataArea); } } if (this.rangeMarkers != null) { Iterator iterator = this.rangeMarkers.iterator(); while (iterator.hasNext()) { Marker marker = (Marker) iterator.next(); drawRangeMarker(g2, this, getRangeAxis(), marker, dataArea); } }// TO DO: these annotations only work with XYPlot, see if it is possible to make ContourPlot a// subclass of XYPlot (DG);// // draw the annotations...// if (this.annotations != null) {// Iterator iterator = this.annotations.iterator();// while (iterator.hasNext()) {// Annotation annotation = (Annotation) iterator.next();// if (annotation instanceof XYAnnotation) {// XYAnnotation xya = (XYAnnotation) annotation;// // get the annotation to draw itself...// xya.draw(g2, this, dataArea, getDomainAxis(), getRangeAxis());// }// }// } g2.setClip(originalClip); g2.setComposite(originalComposite); drawOutline(g2, dataArea); } /** * Draws a representation of the data within the dataArea region, using the * current renderer. * <P> * 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 an optional object for collecting crosshair info. */ public void render(Graphics2D g2, Rectangle2D dataArea, PlotRenderingInfo info, CrosshairState crosshairState) { // now get the data and plot it (the visual representation will depend // on the renderer that has been set)... ContourDataset data = this.getContourDataset(); if (data != null) { ColorBar zAxis = getColorBar(); if (this.clipPath != null) { GeneralPath clipper = getClipPath().draw( g2, dataArea, this.domainAxis, this.rangeAxis ); if (this.clipPath.isClip()) { g2.clip(clipper); } } if (this.renderAsPoints) { pointRenderer(g2, dataArea, info, this, this.domainAxis, this.rangeAxis, zAxis, data, crosshairState); } else { contourRenderer(g2, dataArea, info, this, this.domainAxis, this.rangeAxis, zAxis, data, crosshairState); } // draw vertical crosshair if required... setDomainCrosshairValue(crosshairState.getCrosshairX(), false); if (isDomainCrosshairVisible()) { drawVerticalLine(g2, dataArea, getDomainCrosshairValue(), getDomainCrosshairStroke(), getDomainCrosshairPaint()); } // draw horizontal crosshair if required... setRangeCrosshairValue(crosshairState.getCrosshairY(), false); if (isRangeCrosshairVisible()) { drawHorizontalLine(g2, dataArea, getRangeCrosshairValue(), getRangeCrosshairStroke(), getRangeCrosshairPaint()); } } else if (this.clipPath != null) { getClipPath().draw(g2, dataArea, this.domainAxis, this.rangeAxis); } } /** * Fills the plot. * * @param g2 the graphics device. * @param dataArea the area within which the data is being drawn. * @param info collects information about the drawing. * @param plot the plot (can be used to obtain standard color information etc). * @param horizontalAxis the domain (horizontal) axis. * @param verticalAxis the range (vertical) axis. * @param colorBar the color bar axis. * @param data the dataset. * @param crosshairState information about crosshairs on a plot. */ public void contourRenderer(Graphics2D g2, Rectangle2D dataArea, PlotRenderingInfo info, ContourPlot plot, ValueAxis horizontalAxis, ValueAxis verticalAxis, ColorBar colorBar, ContourDataset data, CrosshairState crosshairState) { // setup for collecting optional entity info... Rectangle2D.Double entityArea = null; EntityCollection entities = null; if (info != null) { entities = info.getOwner().getEntityCollection(); } Rectangle2D.Double rect = null; rect = new Rectangle2D.Double(); //turn off anti-aliasing when filling rectangles Object antiAlias = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); // get the data points Number[] xNumber = data.getXValues(); Number[] yNumber = data.getYValues(); Number[] zNumber = data.getZValues(); double[] x = new double[xNumber.length]; double[] y = new double[yNumber.length]; for (int i = 0; i < x.length; i++) { x[i] = xNumber[i].doubleValue(); y[i] = yNumber[i].doubleValue(); } int[] xIndex = data.indexX(); int[] indexX = data.getXIndices(); boolean vertInverted = ((NumberAxis) verticalAxis).isInverted(); boolean horizInverted = false; if (horizontalAxis instanceof NumberAxis) { horizInverted = ((NumberAxis) horizontalAxis).isInverted(); } double transX = 0.0; double transXm1 = 0.0; double transXp1 = 0.0; double transDXm1 = 0.0; double transDXp1 = 0.0; double transDX = 0.0; double transY = 0.0; double transYm1 = 0.0; double transYp1 = 0.0; double transDYm1 = 0.0; double transDYp1 = 0.0; double transDY = 0.0; int iMax = xIndex[xIndex.length - 1]; for (int k = 0; k < x.length; k++) { int i = xIndex[k]; if (indexX[i] == k) { // this is a new column if (i == 0) { transX = horizontalAxis.valueToJava2D(x[k], dataArea, RectangleEdge.BOTTOM); transXm1 = transX; transXp1 = horizontalAxis.valueToJava2D(x[indexX[i + 1]], dataArea, RectangleEdge.BOTTOM); transDXm1 = Math.abs(0.5 * (transX - transXm1)); transDXp1 = Math.abs(0.5 * (transX - transXp1)); } else if (i == iMax) { transX = horizontalAxis.valueToJava2D(x[k], dataArea, RectangleEdge.BOTTOM); transXm1 = horizontalAxis.valueToJava2D(x[indexX[i - 1]], dataArea, RectangleEdge.BOTTOM); transXp1 = transX; transDXm1 = Math.abs(0.5 * (transX - transXm1)); transDXp1 = Math.abs(0.5 * (transX - transXp1)); } else { transX = horizontalAxis.valueToJava2D(x[k], dataArea, RectangleEdge.BOTTOM); transXp1 = horizontalAxis.valueToJava2D(x[indexX[i + 1]], dataArea, RectangleEdge.BOTTOM); transDXm1 = transDXp1; transDXp1 = Math.abs(0.5 * (transX - transXp1)); } if (horizInverted) { transX -= transDXp1; } else { transX -= transDXm1; } transDX = transDXm1 + transDXp1; transY = verticalAxis.valueToJava2D(y[k], dataArea, RectangleEdge.LEFT); transYm1 = transY; if (k + 1 == y.length) { continue; } transYp1 = verticalAxis.valueToJava2D(y[k + 1], dataArea, RectangleEdge.LEFT); transDYm1 = Math.abs(0.5 * (transY - transYm1)); transDYp1 = Math.abs(0.5 * (transY - transYp1)); } else if ((i < indexX.length - 1 && indexX[i + 1] - 1 == k) || k == x.length - 1) { // end of column transY = verticalAxis.valueToJava2D(y[k], dataArea, RectangleEdge.LEFT); transYm1 = verticalAxis.valueToJava2D(y[k - 1], dataArea, RectangleEdge.LEFT); transYp1 = transY; transDYm1 = Math.abs(0.5 * (transY - transYm1)); transDYp1 = Math.abs(0.5 * (transY - transYp1)); } else { transY = verticalAxis.valueToJava2D(y[k], dataArea, RectangleEdge.LEFT); transYp1 = verticalAxis.valueToJava2D(y[k + 1], dataArea, RectangleEdge.LEFT); transDYm1 = transDYp1; transDYp1 = Math.abs(0.5 * (transY - transYp1)); } if (vertInverted) { transY -= transDYm1; } else { transY -= transDYp1; } transDY = transDYm1 + transDYp1; rect.setRect(transX, transY, transDX, transDY); if (zNumber[k] != null) { g2.setPaint(colorBar.getPaint(zNumber[k].doubleValue())); g2.fill(rect); } else if (this.missingPaint != null) { g2.setPaint(this.missingPaint); g2.fill(rect); } entityArea = rect; // add an entity for the item... if (entities != null) { String tip = ""; if (getToolTipGenerator() != null) { tip = this.toolTipGenerator.generateToolTip(data, k); }// Shape s = g2.getClip();// if (s.contains(rect) || s.intersects(rect)) { String url = null; // if (getURLGenerator() != null) { //dmo: look at this later // url = getURLGenerator().generateURL(data, series, item); // } // Unlike XYItemRenderer, we need to clone entityArea since it reused. ContourEntity entity = new ContourEntity((Rectangle2D.Double) entityArea.clone(), tip, url); entity.setIndex(k); entities.addEntity(entity);// } } // do we need to update the crosshair values? if (plot.isDomainCrosshairLockedOnData()) { if (plot.isRangeCrosshairLockedOnData()) { // both axes crosshairState.updateCrosshairPoint( x[k], y[k], transX, transY, PlotOrientation.VERTICAL ); } else { // just the horizontal axis... crosshairState.updateCrosshairX(transX); } } else { if (plot.isRangeCrosshairLockedOnData()) { // just the vertical axis...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -