A combined category plot where the domain axis is shared.
| Method from org.jfree.chart.plot.CombinedDomainCategoryPlot Detail: |
public void add(CategoryPlot subplot) {
add(subplot, 1);
}
Adds a subplot to the combined chart and sends a PlotChangeEvent
to all registered listeners.
The domain axis for the subplot will be set to null. You
must ensure that the subplot has a non-null range axis. |
public void add(CategoryPlot subplot,
int weight) {
if (subplot == null) {
throw new IllegalArgumentException("Null 'subplot' argument.");
}
if (weight < 1) {
throw new IllegalArgumentException("Require weight >= 1.");
}
subplot.setParent(this);
subplot.setWeight(weight);
subplot.setInsets(new RectangleInsets(0.0, 0.0, 0.0, 0.0));
subplot.setDomainAxis(null);
subplot.setOrientation(getOrientation());
subplot.addChangeListener(this);
this.subplots.add(subplot);
this.totalWeight += weight;
CategoryAxis axis = getDomainAxis();
if (axis != null) {
axis.configure();
}
fireChangeEvent();
}
Adds a subplot to the combined chart and sends a PlotChangeEvent
to all registered listeners.
The domain axis for the subplot will be set to null. You
must ensure that the subplot has a non-null range axis. |
protected AxisSpace calculateAxisSpace(Graphics2D g2,
Rectangle2D plotArea) {
AxisSpace space = new AxisSpace();
PlotOrientation orientation = getOrientation();
// work out the space required by the domain axis...
AxisSpace fixed = getFixedDomainAxisSpace();
if (fixed != null) {
if (orientation == PlotOrientation.HORIZONTAL) {
space.setLeft(fixed.getLeft());
space.setRight(fixed.getRight());
}
else if (orientation == PlotOrientation.VERTICAL) {
space.setTop(fixed.getTop());
space.setBottom(fixed.getBottom());
}
}
else {
CategoryAxis categoryAxis = getDomainAxis();
RectangleEdge categoryEdge = Plot.resolveDomainAxisLocation(
getDomainAxisLocation(), orientation);
if (categoryAxis != null) {
space = categoryAxis.reserveSpace(g2, this, plotArea,
categoryEdge, space);
}
else {
if (getDrawSharedDomainAxis()) {
space = getDomainAxis().reserveSpace(g2, this, plotArea,
categoryEdge, space);
}
}
}
Rectangle2D adjustedPlotArea = space.shrink(plotArea, null);
// work out the maximum height or width of the non-shared axes...
int n = this.subplots.size();
this.subplotAreas = new Rectangle2D[n];
double x = adjustedPlotArea.getX();
double y = adjustedPlotArea.getY();
double usableSize = 0.0;
if (orientation == PlotOrientation.HORIZONTAL) {
usableSize = adjustedPlotArea.getWidth() - this.gap * (n - 1);
}
else if (orientation == PlotOrientation.VERTICAL) {
usableSize = adjustedPlotArea.getHeight() - this.gap * (n - 1);
}
for (int i = 0; i < n; i++) {
CategoryPlot plot = (CategoryPlot) this.subplots.get(i);
// calculate sub-plot area
if (orientation == PlotOrientation.HORIZONTAL) {
double w = usableSize * plot.getWeight() / this.totalWeight;
this.subplotAreas[i] = new Rectangle2D.Double(x, y, w,
adjustedPlotArea.getHeight());
x = x + w + this.gap;
}
else if (orientation == PlotOrientation.VERTICAL) {
double h = usableSize * plot.getWeight() / this.totalWeight;
this.subplotAreas[i] = new Rectangle2D.Double(x, y,
adjustedPlotArea.getWidth(), h);
y = y + h + this.gap;
}
AxisSpace subSpace = plot.calculateRangeAxisSpace(g2,
this.subplotAreas[i], null);
space.ensureAtLeast(subSpace);
}
return space;
}
Calculates the space required for the axes. |
public Object clone() throws CloneNotSupportedException {
CombinedDomainCategoryPlot result
= (CombinedDomainCategoryPlot) super.clone();
result.subplots = (List) ObjectUtilities.deepClone(this.subplots);
for (Iterator it = result.subplots.iterator(); it.hasNext();) {
Plot child = (Plot) it.next();
child.setParent(result);
}
return result;
}
Returns a clone of the plot. |
public void draw(Graphics2D g2,
Rectangle2D area,
Point2D anchor,
PlotState parentState,
PlotRenderingInfo info) {
// set up info collection...
if (info != null) {
info.setPlotArea(area);
}
// adjust the drawing area for plot insets (if any)...
RectangleInsets insets = getInsets();
area.setRect(area.getX() + insets.getLeft(),
area.getY() + insets.getTop(),
area.getWidth() - insets.getLeft() - insets.getRight(),
area.getHeight() - insets.getTop() - insets.getBottom());
// calculate the data area...
setFixedRangeAxisSpaceForSubplots(null);
AxisSpace space = calculateAxisSpace(g2, area);
Rectangle2D dataArea = space.shrink(area, null);
// set the width and height of non-shared axis of all sub-plots
setFixedRangeAxisSpaceForSubplots(space);
// draw the shared axis
CategoryAxis axis = getDomainAxis();
RectangleEdge domainEdge = getDomainAxisEdge();
double cursor = RectangleEdge.coordinate(dataArea, domainEdge);
AxisState axisState = axis.draw(g2, cursor, area, dataArea,
domainEdge, info);
if (parentState == null) {
parentState = new PlotState();
}
parentState.getSharedAxisStates().put(axis, axisState);
// draw all the subplots
for (int i = 0; i < this.subplots.size(); i++) {
CategoryPlot plot = (CategoryPlot) this.subplots.get(i);
PlotRenderingInfo subplotInfo = null;
if (info != null) {
subplotInfo = new PlotRenderingInfo(info.getOwner());
info.addSubplotInfo(subplotInfo);
}
plot.draw(g2, this.subplotAreas[i], null, parentState, subplotInfo);
}
if (info != null) {
info.setDataArea(dataArea);
}
}
Draws the plot on a Java 2D graphics device (such as the screen or a
printer). Will perform all the placement calculations for each of the
sub-plots and then tell these to draw themselves. |
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof CombinedDomainCategoryPlot)) {
return false;
}
if (!super.equals(obj)) {
return false;
}
CombinedDomainCategoryPlot plot = (CombinedDomainCategoryPlot) obj;
if (!ObjectUtilities.equal(this.subplots, plot.subplots)) {
return false;
}
if (this.totalWeight != plot.totalWeight) {
return false;
}
if (this.gap != plot.gap) {
return false;
}
return true;
}
Tests the plot for equality with an arbitrary object. |
public CategoryPlot findSubplot(PlotRenderingInfo info,
Point2D source) {
if (info == null) {
throw new IllegalArgumentException("Null 'info' argument.");
}
if (source == null) {
throw new IllegalArgumentException("Null 'source' argument.");
}
CategoryPlot result = null;
int subplotIndex = info.getSubplotIndex(source);
if (subplotIndex >= 0) {
result = (CategoryPlot) this.subplots.get(subplotIndex);
}
return result;
}
Returns the subplot (if any) that contains the (x, y) point (specified
in Java2D space). |
public List getCategories() {
List result = new java.util.ArrayList();
if (this.subplots != null) {
Iterator iterator = this.subplots.iterator();
while (iterator.hasNext()) {
CategoryPlot plot = (CategoryPlot) iterator.next();
List more = plot.getCategories();
Iterator moreIterator = more.iterator();
while (moreIterator.hasNext()) {
Comparable category = (Comparable) moreIterator.next();
if (!result.contains(category)) {
result.add(category);
}
}
}
}
return Collections.unmodifiableList(result);
}
Returns an unmodifiable list of the categories contained in all the
subplots. |
public List getCategoriesForAxis(CategoryAxis axis) {
// FIXME: this code means that it is not possible to use more than
// one domain axis for the combined plots...
return getCategories();
}
Overridden to return the categories in the subplots. |
public Range getDataRange(ValueAxis axis) {
// override is only for documentation purposes
return super.getDataRange(axis);
}
Returns a range representing the extent of the data values in this plot
(obtained from the subplots) that will be rendered against the specified
axis. NOTE: This method is intended for internal JFreeChart use, and
is public only so that code in the axis classes can call it. Since,
for this class, the domain axis is a CategoryAxis
(not a ValueAxis |
public double getGap() {
return this.gap;
}
Returns the space between subplots. |
public LegendItemCollection getLegendItems() {
LegendItemCollection result = getFixedLegendItems();
if (result == null) {
result = new LegendItemCollection();
if (this.subplots != null) {
Iterator iterator = this.subplots.iterator();
while (iterator.hasNext()) {
CategoryPlot plot = (CategoryPlot) iterator.next();
LegendItemCollection more = plot.getLegendItems();
result.addAll(more);
}
}
}
return result;
}
Returns a collection of legend items for the plot. |
public List getSubplots() {
if (this.subplots != null) {
return Collections.unmodifiableList(this.subplots);
}
else {
return Collections.EMPTY_LIST;
}
}
Returns the list of subplots. The returned list may be empty, but is
never null. |
public void handleClick(int x,
int y,
PlotRenderingInfo info) {
Rectangle2D dataArea = info.getDataArea();
if (dataArea.contains(x, y)) {
for (int i = 0; i < this.subplots.size(); i++) {
CategoryPlot subplot = (CategoryPlot) this.subplots.get(i);
PlotRenderingInfo subplotInfo = info.getSubplotInfo(i);
subplot.handleClick(x, y, subplotInfo);
}
}
}
Handles a 'click' on the plot. |
public void plotChanged(PlotChangeEvent event) {
notifyListeners(event);
}
|
public void remove(CategoryPlot subplot) {
if (subplot == null) {
throw new IllegalArgumentException("Null 'subplot' argument.");
}
int position = -1;
int size = this.subplots.size();
int i = 0;
while (position == -1 && i < size) {
if (this.subplots.get(i) == subplot) {
position = i;
}
i++;
}
if (position != -1) {
this.subplots.remove(position);
subplot.setParent(null);
subplot.removeChangeListener(this);
this.totalWeight -= subplot.getWeight();
CategoryAxis domain = getDomainAxis();
if (domain != null) {
domain.configure();
}
fireChangeEvent();
}
}
Removes a subplot from the combined chart. Potentially, this removes
some unique categories from the overall union of the datasets...so the
domain axis is reconfigured, then a PlotChangeEvent is sent to
all registered listeners. |
protected void setFixedRangeAxisSpaceForSubplots(AxisSpace space) {
Iterator iterator = this.subplots.iterator();
while (iterator.hasNext()) {
CategoryPlot plot = (CategoryPlot) iterator.next();
plot.setFixedRangeAxisSpace(space, false);
}
}
Sets the size (width or height, depending on the orientation of the
plot) for the range axis of each subplot. |
public void setGap(double gap) {
this.gap = gap;
fireChangeEvent();
}
Sets the amount of space between subplots and sends a
PlotChangeEvent to all registered listeners. |
public void setOrientation(PlotOrientation orientation) {
super.setOrientation(orientation);
Iterator iterator = this.subplots.iterator();
while (iterator.hasNext()) {
CategoryPlot plot = (CategoryPlot) iterator.next();
plot.setOrientation(orientation);
}
}
Sets the orientation of the plot (and all subplots). |
public void zoomRangeAxes(double factor,
PlotRenderingInfo info,
Point2D source) {
zoomRangeAxes(factor, info, source, false);
}
Multiplies the range on the range axis/axes by the specified factor. |
public void zoomRangeAxes(double factor,
PlotRenderingInfo info,
Point2D source,
boolean useAnchor) {
// delegate 'info' and 'source' argument checks...
CategoryPlot subplot = findSubplot(info, source);
if (subplot != null) {
subplot.zoomRangeAxes(factor, info, source, useAnchor);
}
else {
// if the source point doesn't fall within a subplot, we do the
// zoom on all subplots...
Iterator iterator = getSubplots().iterator();
while (iterator.hasNext()) {
subplot = (CategoryPlot) iterator.next();
subplot.zoomRangeAxes(factor, info, source, useAnchor);
}
}
}
Multiplies the range on the range axis/axes by the specified factor. |
public void zoomRangeAxes(double lowerPercent,
double upperPercent,
PlotRenderingInfo info,
Point2D source) {
// delegate 'info' and 'source' argument checks...
CategoryPlot subplot = findSubplot(info, source);
if (subplot != null) {
subplot.zoomRangeAxes(lowerPercent, upperPercent, info, source);
}
else {
// if the source point doesn't fall within a subplot, we do the
// zoom on all subplots...
Iterator iterator = getSubplots().iterator();
while (iterator.hasNext()) {
subplot = (CategoryPlot) iterator.next();
subplot.zoomRangeAxes(lowerPercent, upperPercent, info, source);
}
}
}
Zooms in on the range axes. |