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 + -
显示快捷键?