📄 multiplepieplot.java
字号:
* @param paint the paint (<code>null</code> not permitted).
*
* @since 1.0.2
*/
public void setAggregatedItemsPaint(Paint paint) {
if (paint == null) {
throw new IllegalArgumentException("Null 'paint' argument.");
}
this.aggregatedItemsPaint = paint;
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns a short string describing the type of plot.
*
* @return The plot type.
*/
public String getPlotType() {
return "Multiple Pie Plot";
// TODO: need to fetch this from localised resources
}
/**
* Draws the plot on a Java 2D graphics device (such as the screen or a
* printer).
*
* @param g2 the graphics device.
* @param area the area within which the plot should be drawn.
* @param anchor the anchor point (<code>null</code> permitted).
* @param parentState the state from the parent plot, if there is one.
* @param info collects info about the drawing.
*/
public void draw(Graphics2D g2,
Rectangle2D area,
Point2D anchor,
PlotState parentState,
PlotRenderingInfo info) {
// adjust the drawing area for the plot insets (if any)...
RectangleInsets insets = getInsets();
insets.trim(area);
drawBackground(g2, area);
drawOutline(g2, area);
// check that there is some data to display...
if (DatasetUtilities.isEmptyOrNull(this.dataset)) {
drawNoDataMessage(g2, area);
return;
}
int pieCount = 0;
if (this.dataExtractOrder == TableOrder.BY_ROW) {
pieCount = this.dataset.getRowCount();
}
else {
pieCount = this.dataset.getColumnCount();
}
// the columns variable is always >= rows
int displayCols = (int) Math.ceil(Math.sqrt(pieCount));
int displayRows
= (int) Math.ceil((double) pieCount / (double) displayCols);
// swap rows and columns to match plotArea shape
if (displayCols > displayRows && area.getWidth() < area.getHeight()) {
int temp = displayCols;
displayCols = displayRows;
displayRows = temp;
}
prefetchSectionPaints();
int x = (int) area.getX();
int y = (int) area.getY();
int width = ((int) area.getWidth()) / displayCols;
int height = ((int) area.getHeight()) / displayRows;
int row = 0;
int column = 0;
int diff = (displayRows * displayCols) - pieCount;
int xoffset = 0;
Rectangle rect = new Rectangle();
for (int pieIndex = 0; pieIndex < pieCount; pieIndex++) {
rect.setBounds(x + xoffset + (width * column), y + (height * row),
width, height);
String title = null;
if (this.dataExtractOrder == TableOrder.BY_ROW) {
title = this.dataset.getRowKey(pieIndex).toString();
}
else {
title = this.dataset.getColumnKey(pieIndex).toString();
}
this.pieChart.setTitle(title);
PieDataset piedataset = null;
PieDataset dd = new CategoryToPieDataset(this.dataset,
this.dataExtractOrder, pieIndex);
if (this.limit > 0.0) {
piedataset = DatasetUtilities.createConsolidatedPieDataset(
dd, this.aggregatedItemsKey, this.limit);
}
else {
piedataset = dd;
}
PiePlot piePlot = (PiePlot) this.pieChart.getPlot();
piePlot.setDataset(piedataset);
piePlot.setPieIndex(pieIndex);
// update the section colors to match the global colors...
for (int i = 0; i < piedataset.getItemCount(); i++) {
Comparable key = piedataset.getKey(i);
Paint p;
if (key.equals(this.aggregatedItemsKey)) {
p = this.aggregatedItemsPaint;
}
else {
p = (Paint) this.sectionPaints.get(key);
}
piePlot.setSectionPaint(key, p);
}
ChartRenderingInfo subinfo = null;
if (info != null) {
subinfo = new ChartRenderingInfo();
}
this.pieChart.draw(g2, rect, subinfo);
if (info != null) {
info.getOwner().getEntityCollection().addAll(
subinfo.getEntityCollection());
info.addSubplotInfo(subinfo.getPlotInfo());
}
++column;
if (column == displayCols) {
column = 0;
++row;
if (row == displayRows - 1 && diff != 0) {
xoffset = (diff * width) / 2;
}
}
}
}
/**
* For each key in the dataset, check the <code>sectionPaints</code>
* cache to see if a paint is associated with that key and, if not,
* fetch one from the drawing supplier. These colors are cached so that
* the legend and all the subplots use consistent colors.
*/
private void prefetchSectionPaints() {
// pre-fetch the colors for each key...this is because the subplots
// may not display every key, but we need the coloring to be
// consistent...
PiePlot piePlot = (PiePlot) getPieChart().getPlot();
if (this.dataExtractOrder == TableOrder.BY_ROW) {
// column keys provide potential keys for individual pies
for (int c = 0; c < this.dataset.getColumnCount(); c++) {
Comparable key = this.dataset.getColumnKey(c);
Paint p = piePlot.getSectionPaint(key);
if (p == null) {
p = (Paint) this.sectionPaints.get(key);
if (p == null) {
p = getDrawingSupplier().getNextPaint();
}
}
this.sectionPaints.put(key, p);
}
}
else {
// row keys provide potential keys for individual pies
for (int r = 0; r < this.dataset.getRowCount(); r++) {
Comparable key = this.dataset.getRowKey(r);
Paint p = piePlot.getSectionPaint(key);
if (p == null) {
p = (Paint) this.sectionPaints.get(key);
if (p == null) {
p = getDrawingSupplier().getNextPaint();
}
}
this.sectionPaints.put(key, p);
}
}
}
/**
* Returns a collection of legend items for the pie chart.
*
* @return The legend items.
*/
public LegendItemCollection getLegendItems() {
LegendItemCollection result = new LegendItemCollection();
if (this.dataset != null) {
List keys = null;
prefetchSectionPaints();
if (this.dataExtractOrder == TableOrder.BY_ROW) {
keys = this.dataset.getColumnKeys();
}
else if (this.dataExtractOrder == TableOrder.BY_COLUMN) {
keys = this.dataset.getRowKeys();
}
if (keys != null) {
int section = 0;
Iterator iterator = keys.iterator();
while (iterator.hasNext()) {
Comparable key = (Comparable) iterator.next();
String label = key.toString();
String description = label;
Paint paint = (Paint) this.sectionPaints.get(key);
LegendItem item = new LegendItem(label, description,
null, null, Plot.DEFAULT_LEGEND_ITEM_CIRCLE,
paint, Plot.DEFAULT_OUTLINE_STROKE, paint);
item.setDataset(getDataset());
result.add(item);
section++;
}
}
if (this.limit > 0.0) {
result.add(new LegendItem(this.aggregatedItemsKey.toString(),
this.aggregatedItemsKey.toString(), null, null,
Plot.DEFAULT_LEGEND_ITEM_CIRCLE,
this.aggregatedItemsPaint,
Plot.DEFAULT_OUTLINE_STROKE,
this.aggregatedItemsPaint));
}
}
return result;
}
/**
* Tests this plot for equality with an arbitrary object. Note that the
* plot's dataset is not considered in the equality test.
*
* @param obj the object (<code>null</code> permitted).
*
* @return <code>true</code> if this plot is equal to <code>obj</code>, and
* <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof MultiplePiePlot)) {
return false;
}
MultiplePiePlot that = (MultiplePiePlot) obj;
if (this.dataExtractOrder != that.dataExtractOrder) {
return false;
}
if (this.limit != that.limit) {
return false;
}
if (!this.aggregatedItemsKey.equals(that.aggregatedItemsKey)) {
return false;
}
if (!PaintUtilities.equal(this.aggregatedItemsPaint,
that.aggregatedItemsPaint)) {
return false;
}
if (!ObjectUtilities.equal(this.pieChart, that.pieChart)) {
return false;
}
if (!super.equals(obj)) {
return false;
}
return true;
}
/**
* Provides serialization support.
*
* @param stream the output stream.
*
* @throws IOException if there is an I/O error.
*/
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.aggregatedItemsPaint, stream);
}
/**
* Provides serialization support.
*
* @param stream the input stream.
*
* @throws IOException if there is an I/O error.
* @throws ClassNotFoundException if there is a classpath problem.
*/
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.aggregatedItemsPaint = SerialUtilities.readPaint(stream);
this.sectionPaints = new HashMap();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -