📄 pieplot.java
字号:
}
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 = 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 po
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -