pieplot.java
来自「JfreeChart 常用图表例子」· Java 代码 · 共 1,886 行 · 第 1/5 页
JAVA
1,886 行
if (!DatasetUtilities.isEmptyOrNull(this.dataset)) { drawPie(g2, area, info); } else { drawNoDataMessage(g2, area); } g2.setClip(savedClip); g2.setComposite(originalComposite); drawOutline(g2, area); } /** * Draws the pie. * * @param g2 the graphics device. * @param plotArea the plot area. * @param info chart rendering info. */ protected void drawPie(Graphics2D g2, Rectangle2D plotArea, PlotRenderingInfo info) { PiePlotState state = initialise(g2, plotArea, this, null, info); // adjust the plot area for interior spacing and labels... double labelWidth = 0.0; if (this.labelGenerator != null) { labelWidth = this.labelGap + this.maximumLabelWidth + this.labelLinkMargin; } double gapHorizontal = plotArea.getWidth() * (this.interiorGap + labelWidth); double gapVertical = plotArea.getHeight() * this.interiorGap; double linkX = plotArea.getX() + gapHorizontal / 2; double linkY = plotArea.getY() + gapVertical / 2; double linkW = plotArea.getWidth() - gapHorizontal; double linkH = plotArea.getHeight() - gapVertical; // make the link area a square if the pie chart is to be circular... if (this.circular) { double min = Math.min(linkW, linkH) / 2; linkX = (linkX + linkX + linkW) / 2 - min; linkY = (linkY + linkY + linkH) / 2 - min; linkW = 2 * min; linkH = 2 * min; } // the link area defines the dog leg points for the linking lines to // the labels Rectangle2D linkArea = new Rectangle2D.Double( linkX, linkY, linkW, linkH ); state.setLinkArea(linkArea); // the explode area defines the max circle/ellipse for the exploded // pie sections. it is defined by shrinking the linkArea by the // linkMargin factor. double hh = linkArea.getWidth() * this.labelLinkMargin; double vv = linkArea.getHeight() * this.labelLinkMargin; Rectangle2D explodeArea = new Rectangle2D.Double( linkX + hh / 2.0, linkY + vv / 2.0, linkW - hh, linkH - vv ); state.setExplodedPieArea(explodeArea); // the pie area defines the circle/ellipse for regular pie sections. // it is defined by shrinking the explodeArea by the explodeMargin // factor. double maximumExplodePercent = getMaximumExplodePercent(); double percent = maximumExplodePercent / (1.0 + maximumExplodePercent); double h1 = explodeArea.getWidth() * percent; double v1 = explodeArea.getHeight() * percent; Rectangle2D pieArea = new Rectangle2D.Double( explodeArea.getX() + h1 / 2.0, explodeArea.getY() + v1 / 2.0, explodeArea.getWidth() - h1, explodeArea.getHeight() - v1 ); state.setPieArea(pieArea); state.setPieCenterX(pieArea.getCenterX()); state.setPieCenterY(pieArea.getCenterY()); state.setPieWRadius(pieArea.getWidth() / 2.0); state.setPieHRadius(pieArea.getHeight() / 2.0); // plot the data (unless the dataset is null)... if ((this.dataset != null) && (this.dataset.getKeys().size() > 0)) { List keys = this.dataset.getKeys(); double totalValue = DatasetUtilities.calculatePieDatasetTotal(this.dataset); int passesRequired = state.getPassesRequired(); for (int pass = 0; pass < passesRequired; pass++) { double runningTotal = 0.0; for (int section = 0; section < keys.size(); section++) { Number n = this.dataset.getValue(section); if (n != null) { double value = n.doubleValue(); if (value > 0.0) { runningTotal += value; drawItem(g2, section, explodeArea, state, pass); } } } } drawLabels(g2, keys, totalValue, plotArea, linkArea, state); } else { drawNoDataMessage(g2, plotArea); } } /** * Draws a single data item. * * @param g2 the graphics device (<code>null</code> not permitted). * @param section the section index. * @param dataArea the data plot area. * @param state state information for one chart. * @param currentPass the current pass index. */ protected void drawItem(Graphics2D g2, int section, Rectangle2D dataArea, PiePlotState state, int currentPass) { Number n = this.dataset.getValue(section); if (n == null) { return; } double value = n.doubleValue(); double angle1 = 0.0; double angle2 = 0.0; 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 = ShapeUtilities.createTranslatedShape( 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.add(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 (this.ignoreZeroValues ? v > 0.0 : 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); 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); l
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?