📄 pielabeldistributor.java
字号:
/* =========================================================== * JFreeChart : a free chart library for the Java(tm) platform * =========================================================== * * (C) Copyright 2000-2004, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jfreechart/index.html * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------------------ * PieLabelDistributor.java * ------------------------ * (C) Copyright 2004, by Object Refinery Limited and Contributors. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): -; * * $Id: PieLabelDistributor.java,v 1.7 2004/06/03 15:05:56 mungady Exp $ * * Changes * ------- * 08-Mar-2004 : Version 1 (DG); * */package org.jfree.chart.plot;import java.util.ArrayList;import java.util.Collections;import java.util.List;/** * This class distributes the section labels for one side of a pie chart so that they do not * overlap. */public class PieLabelDistributor { /** The label records. */ private List labels; /** The minimum gap. */ private double minGap = 4.0; /** * Creates a new distributor. * * @param labelCount the number of labels. */ public PieLabelDistributor(int labelCount) { this.labels = new ArrayList(labelCount); } /** * Returns a label record from the list. * * @param index the index. * * @return the label record. */ public PieLabelRecord getPieLabelRecord(int index) { return (PieLabelRecord) this.labels.get(index); } /** * Adds a label record. * * @param record the label record. */ public void addPieLabelRecord(PieLabelRecord record) { this.labels.add(record); } /** * Returns the number of items in the list. * * @return the item count. */ public int getItemCount() { return this.labels.size(); } /** * Distributes the labels. * * @param minY the minimum y-coordinate in Java2D-space. * @param height the height. */ public void distributeLabels(double minY, double height) { sort(); if (isOverlap()) { adjustInwards(); } // if still overlapping, do something else... if (isOverlap()) { adjustDownwards(minY, height); } if (isOverlap()) { adjustUpwards(minY, height); } if (isOverlap()) { spreadEvenly(minY, height); } } /** * Returns <code>true</code> if there are overlapping labels in the list, and <code>false</code> * otherwise. * * @return A boolean. */ private boolean isOverlap() { double y = 0.0; for (int i = 0; i < this.labels.size(); i++) { PieLabelRecord plr = getPieLabelRecord(i); if (y > plr.getLowerY()) { return true; } y = plr.getUpperY(); } return false; } /** * Adjusts the y-coordinate for the labels in towards the center in an attempt to fix * overlapping. */ protected void adjustInwards() { int lower = 0; int upper = this.labels.size() - 1; while (upper > lower) { if (lower < upper - 1) { PieLabelRecord r0 = getPieLabelRecord(lower); PieLabelRecord r1 = getPieLabelRecord(lower + 1); if (r1.getLowerY() < r0.getUpperY()) { double adjust = r0.getUpperY() - r1.getLowerY() + this.minGap; r1.setAllocatedY(r1.getAllocatedY() + adjust); } } PieLabelRecord r2 = getPieLabelRecord(upper - 1); PieLabelRecord r3 = getPieLabelRecord(upper); if (r2.getUpperY() > r3.getLowerY()) { double adjust = (r2.getUpperY() - r3.getLowerY()) + this.minGap; r2.setAllocatedY(r2.getAllocatedY() - adjust); } lower++; upper--; } } /** * Any labels that are overlapping are moved down in an attempt to eliminate the overlaps. * * @param minY the minimum y value (in Java2D coordinate space). * @param height the height available for all labels. */ protected void adjustDownwards(double minY, double height) { for (int i = 0; i < this.labels.size() - 1; i++) { PieLabelRecord record0 = getPieLabelRecord(i); PieLabelRecord record1 = getPieLabelRecord(i + 1); if (record1.getLowerY() < record0.getUpperY()) { record1.setAllocatedY( Math.min( minY + height, record0.getUpperY() + this.minGap + record1.getLabelHeight() / 2.0 ) ); } } } /** * Any labels that are overlapping are moved up in an attempt to eliminate the overlaps. * * @param minY the minimum y value (in Java2D coordinate space). * @param height the height available for all labels. */ protected void adjustUpwards(double minY, double height) { for (int i = this.labels.size() - 1; i > 0 ; i--) { PieLabelRecord record0 = getPieLabelRecord(i); PieLabelRecord record1 = getPieLabelRecord(i - 1); if (record1.getUpperY() > record0.getLowerY()) { record1.setAllocatedY( Math.max( minY, record0.getLowerY() - this.minGap - record1.getLabelHeight() / 2.0 ) ); } } } /** * Labels are spaced evenly in the available space in an attempt to eliminate the overlaps. * * @param minY the minimum y value (in Java2D coordinate space). * @param height the height available for all labels. */ protected void spreadEvenly(double minY, double height) { double y = minY; double sumOfLabelHeights = 0.0; for (int i = 0; i < this.labels.size(); i++) { sumOfLabelHeights += getPieLabelRecord(i).getLabelHeight(); } double gap = height - sumOfLabelHeights; if (this.labels.size() > 1) { gap = gap / (this.labels.size() - 1); } for (int i = 0; i < this.labels.size(); i++) { PieLabelRecord record = getPieLabelRecord(i); y = y + record.getLabelHeight() / 2.0; record.setAllocatedY(y); y = y + record.getLabelHeight() / 2.0 + gap; } } /** * Sorts the label records into ascending order by y-value. */ public void sort() { Collections.sort(this.labels); } /** * Returns a string containing a description of the object for debugging purposes. * * @return a string. */ public String toString() { String result = ""; for (int i = 0; i < this.labels.size(); i++) { result = result + getPieLabelRecord(i).toString() + "\n"; } return result; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -