/** * Draws the background to the specified graphics device. If the dial frame specifies a window, * the clipping region will already have been set to this window before this method is called. * * @param g2 the graphics device (<code>null</code> not permitted). * @param plot the plot (ignored here). * @param frame the dial frame (ignored here). * @param view the view rectangle (<code>null</code> not permitted). */ @Override public void draw(Graphics2D g2, DialPlot plot, Rectangle2D frame, Rectangle2D view) { // work out the anchor point Rectangle2D f = DialPlot.rectangleByRadius(frame, this.radius, this.radius); Arc2D arc = new Arc2D.Double(f, this.angle, 0.0, Arc2D.OPEN); Point2D pt = arc.getStartPoint(); // the indicator bounds is calculated from the templateValue (which // determines the minimum size), the maxTemplateValue (which, if // specified, provides a maximum size) and the actual value FontMetrics fm = g2.getFontMetrics(this.font); double value = plot.getValue(this.datasetIndex); String valueStr = this.formatter.format(value); Rectangle2D valueBounds = TextUtilities.getTextBounds(valueStr, g2, fm); // calculate the bounds of the template value String s = this.formatter.format(this.templateValue); Rectangle2D tb = TextUtilities.getTextBounds(s, g2, fm); double minW = tb.getWidth(); double minH = tb.getHeight(); double maxW = Double.MAX_VALUE; double maxH = Double.MAX_VALUE; if (this.maxTemplateValue != null) { s = this.formatter.format(this.maxTemplateValue); tb = TextUtilities.getTextBounds(s, g2, fm); maxW = Math.max(tb.getWidth(), minW); maxH = Math.max(tb.getHeight(), minH); } double w = fixToRange(valueBounds.getWidth(), minW, maxW); double h = fixToRange(valueBounds.getHeight(), minH, maxH); // align this rectangle to the frameAnchor Rectangle2D bounds = RectangleAnchor.createRectangle(new Size2D(w, h), pt.getX(), pt.getY(), this.frameAnchor); // add the insets Rectangle2D fb = this.insets.createOutsetRectangle(bounds); // draw the background g2.setPaint(this.backgroundPaint); g2.fill(fb); // draw the border g2.setStroke(this.outlineStroke); g2.setPaint(this.outlinePaint); g2.draw(fb); // now find the text anchor point Shape savedClip = g2.getClip(); g2.clip(fb); Point2D pt2 = RectangleAnchor.coordinates(bounds, this.valueAnchor); g2.setPaint(this.paint); g2.setFont(this.font); TextUtilities.drawAlignedString( valueStr, g2, (float) pt2.getX(), (float) pt2.getY(), this.textAnchor); g2.setClip(savedClip); }
@Override public void draw(Graphics2D g2, DialPlot plot, Rectangle2D frame, Rectangle2D view) { g2.setPaint(Color.blue); g2.setStroke(this.outlineStroke); Rectangle2D lengthRect = DialPlot.rectangleByRadius(frame, getRadius(), getRadius()); Rectangle2D widthRect = DialPlot.rectangleByRadius(frame, getWidthRadius(), getWidthRadius()); double value = plot.getValue(getDatasetIndex()); DialScale scale = plot.getScaleForDataset(getDatasetIndex()); double angle = scale.valueToAngle(value); Arc2D arc1 = new Arc2D.Double(lengthRect, angle, 0, Arc2D.OPEN); Point2D pt1 = arc1.getEndPoint(); Arc2D arc2 = new Arc2D.Double(widthRect, angle - 90.0, 180.0, Arc2D.OPEN); Point2D pt2 = arc2.getStartPoint(); Point2D pt3 = arc2.getEndPoint(); Arc2D arc3 = new Arc2D.Double(widthRect, angle - 180.0, 0.0, Arc2D.OPEN); Point2D pt4 = arc3.getStartPoint(); GeneralPath gp = new GeneralPath(); gp.moveTo((float) pt1.getX(), (float) pt1.getY()); gp.lineTo((float) pt2.getX(), (float) pt2.getY()); gp.lineTo((float) pt4.getX(), (float) pt4.getY()); gp.lineTo((float) pt3.getX(), (float) pt3.getY()); gp.closePath(); g2.setPaint(getFillPaint()); g2.fill(gp); g2.setPaint(getOutlinePaint()); Line2D line = new Line2D.Double(frame.getCenterX(), frame.getCenterY(), pt1.getX(), pt1.getY()); g2.draw(line); line.setLine(pt2, pt3); g2.draw(line); line.setLine(pt3, pt1); g2.draw(line); line.setLine(pt2, pt1); g2.draw(line); line.setLine(pt2, pt4); g2.draw(line); line.setLine(pt3, pt4); g2.draw(line); }
/** @param arc the Arc2D object to be converted */ public Element toSVG(Arc2D arc) { double ext = arc.getAngleExtent(); double width = arc.getWidth(); double height = arc.getHeight(); if (width == 0 || height == 0) { Line2D line = new Line2D.Double(arc.getX(), arc.getY(), arc.getX() + width, arc.getY() + height); if (svgLine == null) { svgLine = new SVGLine(generatorContext); } return svgLine.toSVG(line); } if (ext >= 360 || ext <= -360) { Ellipse2D ellipse = new Ellipse2D.Double(arc.getX(), arc.getY(), width, height); if (svgEllipse == null) { svgEllipse = new SVGEllipse(generatorContext); } return svgEllipse.toSVG(ellipse); } Element svgPath = generatorContext.domFactory.createElementNS(SVG_NAMESPACE_URI, SVG_PATH_TAG); StringBuffer d = new StringBuffer(""); Point2D startPt = arc.getStartPoint(); Point2D endPt = arc.getEndPoint(); int type = arc.getArcType(); d.append(PATH_MOVE); d.append(doubleString(startPt.getX())); d.append(SPACE); d.append(doubleString(startPt.getY())); d.append(SPACE); d.append(PATH_ARC); d.append(doubleString(width / 2)); d.append(SPACE); d.append(doubleString(height / 2)); d.append(SPACE); d.append("0"); // no rotation with J2D arc. d.append(SPACE); if (ext > 0) { // CCW sweep case, ext > 0 if (ext > 180) d.append("1"); // use large arc. else d.append("0"); // use small arc. d.append(SPACE); d.append("0"); // sweep ccw } else { // CW sweep case, ext < 0 if (ext < -180) d.append("1"); // use large arc. else d.append("0"); // use small arc. d.append(SPACE); d.append("1"); // sweep cw } d.append(SPACE); d.append(doubleString(endPt.getX())); d.append(SPACE); d.append(doubleString(endPt.getY())); if (type == Arc2D.CHORD) { d.append(PATH_CLOSE); } else if (type == Arc2D.PIE) { double cx = arc.getX() + width / 2; double cy = arc.getY() + height / 2; d.append(PATH_LINE_TO); d.append(SPACE); d.append(doubleString(cx)); d.append(SPACE); d.append(doubleString(cy)); d.append(SPACE); d.append(PATH_CLOSE); } svgPath.setAttributeNS(null, SVG_D_ATTRIBUTE, d.toString()); return svgPath; }