📄 pieplot.java
字号:
if (this.direction == Rotation.CLOCKWISE) { angle1 = state.getLatestAngle(); angle2 = angle1 - value / state.getTotal() * 360.0; } else if (this.direction == Rotation.ANTICLOCKWISE) { angle1 = state.getLatestAngle(); angle2 = angle1 + value / state.getTotal() * 360.0; } else { throw new IllegalStateException("Rotation type not recognised."); } double angle = (angle2 - angle1); if (Math.abs(angle) > getMinimumArcAngleToDraw()) { double ep = 0.0; double mep = getMaximumExplodePercent(); if (mep > 0.0) { ep = getExplodePercent(section) / mep; } Rectangle2D arcBounds = getArcBounds( state.getPieArea(), state.getExplodedPieArea(), angle1, angle, ep ); Arc2D.Double arc = new Arc2D.Double(arcBounds, angle1, angle, Arc2D.PIE); if (currentPass == 0) { if (this.shadowPaint != null) { Shape shadowArc = ShapeUtils.translateShape( arc, (float) this.shadowXOffset, (float) this.shadowYOffset ); g2.setPaint(this.shadowPaint); g2.fill(shadowArc); } } else if (currentPass == 1) { Paint paint = getSectionPaint(section); g2.setPaint(paint); g2.fill(arc); Paint outlinePaint = getSectionOutlinePaint(section); Stroke outlineStroke = getSectionOutlineStroke(section); if (outlinePaint != null && outlineStroke != null) { g2.setPaint(outlinePaint); g2.setStroke(outlineStroke); g2.draw(arc); } // update the linking line target for later // add an entity for the pie section if (state.getInfo() != null) { EntityCollection entities = state.getInfo().getOwner().getEntityCollection(); if (entities != null) { Comparable key = this.dataset.getKey(section); String tip = null; if (this.toolTipGenerator != null) { tip = this.toolTipGenerator.generateToolTip(this.dataset, key); } String url = null; if (this.urlGenerator != null) { url = this.urlGenerator.generateURL(this.dataset, key, this.pieIndex); } PieSectionEntity entity = new PieSectionEntity( arc, this.dataset, this.pieIndex, section, key, tip, url ); entities.addEntity(entity); } } } } state.setLatestAngle(angle2); } /** * Draws the labels for the pie sections. * * @param g2 the graphics device. * @param keys the keys. * @param totalValue the total value. * @param plotArea the plot area. * @param linkArea the link area. * @param state the state. */ protected void drawLabels(Graphics2D g2, List keys, double totalValue, Rectangle2D plotArea, Rectangle2D linkArea, PiePlotState state) { Composite originalComposite = g2.getComposite(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); // classify the keys according to which side the label will appear... DefaultKeyedValues leftKeys = new DefaultKeyedValues(); DefaultKeyedValues rightKeys = new DefaultKeyedValues(); double runningTotal1 = 0.0; Iterator iterator1 = keys.iterator(); while (iterator1.hasNext()) { Comparable key = (Comparable) iterator1.next(); Number n = this.dataset.getValue(key); if (n != null) { double v = n.doubleValue(); if (v > 0.0) { runningTotal1 = runningTotal1 + v; // work out the mid angle (0 - 90 and 270 - 360) = right, otherwise left double mid = this.startAngle + (this.direction.getFactor() * ((runningTotal1 - v / 2.0) * 360) / totalValue); if (Math.cos(Math.toRadians(mid)) < 0.0) { leftKeys.addValue(key, new Double(mid)); } else { rightKeys.addValue(key, new Double(mid)); } } } } g2.setFont(getLabelFont()); float maxLabelWidth = (float) (getMaximumLabelWidth() * plotArea.getWidth()); // draw the left labels... if (this.labelGenerator != null) { drawLeftLabels(leftKeys, g2, plotArea, linkArea, maxLabelWidth, state); drawRightLabels(rightKeys, g2, plotArea, linkArea, maxLabelWidth, state); } g2.setComposite(originalComposite); } /** * Draws the left labels. * * @param leftKeys the keys. * @param g2 the graphics device. * @param plotArea the plot area. * @param linkArea the link area. * @param maxLabelWidth the maximum label width. * @param state the state. */ protected void drawLeftLabels(KeyedValues leftKeys, Graphics2D g2, Rectangle2D plotArea, Rectangle2D linkArea, float maxLabelWidth, PiePlotState state) { PieLabelDistributor distributor1 = new PieLabelDistributor(leftKeys.getItemCount()); double lGap = plotArea.getWidth() * this.labelGap; double verticalLinkRadius = state.getLinkArea().getHeight() / 2.0; for (int i = 0; i < leftKeys.getItemCount(); i++) { String label = this.labelGenerator.generateSectionLabel( this.dataset, leftKeys.getKey(i) ); if (label != null) { TextBlock block = TextUtilities.createTextBlock( label, this.labelFont, this.labelPaint, maxLabelWidth, new G2TextMeasurer(g2) ); TextBox labelBox = new TextBox(block); labelBox.setBackgroundPaint(this.labelBackgroundPaint); labelBox.setOutlinePaint(this.labelOutlinePaint); labelBox.setOutlineStroke(this.labelOutlineStroke); labelBox.setShadowPaint(this.labelShadowPaint); double theta = Math.toRadians(leftKeys.getValue(i).doubleValue()); double baseY = state.getPieCenterY() - Math.sin(theta) * verticalLinkRadius; double hh = labelBox.getHeight(g2); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Label height = " + hh); } distributor1.addPieLabelRecord( new PieLabelRecord( leftKeys.getKey(i), theta, baseY, labelBox, hh, lGap / 2.0 + lGap / 2.0 * -Math.cos(theta), 0.9 + getExplodePercent(this.dataset.getIndex(leftKeys.getKey(i))) ) ); } } distributor1.distributeLabels(plotArea.getMinY(), plotArea.getHeight()); for (int i = 0; i < distributor1.getItemCount(); i++) { drawLeftLabel(g2, state, distributor1.getPieLabelRecord(i)); } } /** * Draws the right labels. * * @param keys the keys. * @param g2 the graphics device. * @param plotArea the plot area. * @param linkArea the link area. * @param maxLabelWidth the maximum label width. * @param state the state. */ protected void drawRightLabels(KeyedValues keys, Graphics2D g2, Rectangle2D plotArea, Rectangle2D linkArea, float maxLabelWidth, PiePlotState state) { // draw the right labels... PieLabelDistributor distributor2 = new PieLabelDistributor(keys.getItemCount()); double lGap = plotArea.getWidth() * this.labelGap; double verticalLinkRadius = state.getLinkArea().getHeight() / 2.0; for (int i = 0; i < keys.getItemCount(); i++) { String label = this.labelGenerator.generateSectionLabel( this.dataset, keys.getKey(i) ); if (label != null) { TextBlock block = TextUtilities.createTextBlock( label, this.labelFont, this.labelPaint, maxLabelWidth, new G2TextMeasurer(g2) ); TextBox labelBox = new TextBox(block); labelBox.setBackgroundPaint(this.labelBackgroundPaint); labelBox.setOutlinePaint(this.labelOutlinePaint); labelBox.setOutlineStroke(this.labelOutlineStroke); labelBox.setShadowPaint(this.labelShadowPaint); double theta = Math.toRadians(keys.getValue(i).doubleValue()); double baseY = state.getPieCenterY() - Math.sin(theta) * verticalLinkRadius; double hh = labelBox.getHeight(g2); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Label height = " + hh); } distributor2.addPieLabelRecord( new PieLabelRecord( keys.getKey(i), theta, baseY, labelBox, hh, lGap / 2.0 + lGap / 2.0 * Math.cos(theta), 0.9 + getExplodePercent(this.dataset.getIndex(keys.getKey(i))) ) ); } } distributor2.distributeLabels(linkArea.getMinY(), linkArea.getHeight()); for (int i = 0; i < distributor2.getItemCount(); i++) { drawRightLabel(g2, state, distributor2.getPieLabelRecord(i)); } } /** * Returns a collection of legend items for the pie chart. * * @return The legend items (never <code>null</code>). */ public LegendItemCollection getLegendItems() { LegendItemCollection result = new LegendItemCollection(); List keys = null; if (this.dataset != null) { keys = this.dataset.getKeys(); int section = 0; Iterator iterator = keys.iterator(); while (iterator.hasNext()) { Comparable key = (Comparable) iterator.next(); Number n = this.dataset.getValue(key); if (n != null || !this.ignoreNullValues) { String label = key.toString(); String description = label; Shape shape = null; Paint paint = getSectionPaint(section); Paint outlinePaint = getSectionOutlinePaint(section); Stroke stroke = getSectionOutlineStroke(section); LegendItem item = new LegendItem( label, description, shape, true, paint, stroke, outlinePaint, stroke ); result.add(item); section++; } } } return result; } /** * Returns a short string describing the type of plot. * * @return the plot type. */ public String getPlotType() { return localizationResources.getString("Pie_Plot"); } /** * A zoom method that does nothing. * <p> * Plots are required to support the zoom operation. In the case of a pie * 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) { // no zooming for pie plots } /** * Returns a rectangle that can be used to create a pie section (taking * into account the amount by which the pie section is 'exploded'). * * @param unexploded the area inside which the unexploded pie sections are drawn. * @param exploded the area inside which the exploded pie sections are drawn. * @param angle the start angle. * @param extent the extent of the arc. * @param explodePercent the amount by which the pie section is exploded. * * @return a rectangle that can be used to create a pie section. */ protected Rectangle2D getArcBounds(Rectangle2D unexploded, Rectangle2D exploded, double angle, double extent, double explodePercent) { if (explodePercent == 0.0) { return unexploded; } else { Arc2D arc1 = new Arc2D.Double(unexploded, angle, extent / 2, Arc2D.OPEN); Point2D point1 = arc1.getEndPoint(); Arc2D.Double arc2 = new Arc2D.Double(exploded, angle, extent / 2, Arc2D.OPEN); Point2D point2 = arc2.getEndPoint(); double deltaX = (point1.getX() - point2.getX()) * explodePercent; double deltaY = (point1.getY() - point2.getY()) * explodePercent; return new Rectangle2D.Double(unexploded.getX() - deltaX, unexploded.getY() - deltaY, unexploded.getWidth(), unexploded.getHeight()); } } /** * Draws a section label on the left side of the pie chart. * * @param g2 the graphics device. * @param state the state. * @param record the label record. */ protected void drawLeftLabel(Graphics2D g2, PiePlotState state, PieLabelRecord record) { double theta = record.getAngle(); double linkX = state.getPieCenterX() + Math.cos(theta) * state.getPieWRadius() * record.getLinkPercent(); double linkY = state.getPieCenterY() - Math.sin(theta) * state.getPieHRadius() * record.getLinkPercent(); double elbowX = state.getPieCenterX() + Math.cos(theta) * state.getLinkArea().getWidth() / 2.0; double elbowY = state.getPieCenterY() - Math.sin(theta) * state.getLinkArea().getHeight() / 2.0; double anchorX = state.getLinkArea().getMinX(); double anchorY = elbowY; double targetX = anchorX - record.getGap(); double targetY = record.getAllocatedY(); g2.setPaint(this.labelLinkPaint); g2.setStroke(this.labelLinkStroke); g2.draw(new Line2D.Double(linkX, linkY, elbowX, elbowY)); g2.draw(new Line2D.Double(anchorX, anchorY, elbowX, elbowY)); g2.draw(new Line2D.Double(anchorX, anchorY, targetX, targetY)); TextBox tb = record.getLabel();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -