Skip to content

Commit

Permalink
Add flags for min and max outliers as suggested in #79.
Browse files Browse the repository at this point in the history
  • Loading branch information
jfree committed Nov 15, 2020
1 parent b42f388 commit c1a6c13
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 63 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ History
- fixed `LayeredBarRenderer` (bugs #169 and #175);
- update French translations (bug #186);
- fix "Save_as" entries in localisation files (bug #184);
- add flags for visibility of outliers in `BoxAndWhiskerRenderer` ([#79](https://github.com/jfree/jfreechart/pull/79));
- added generics;
- `DefaultIntervalCategoryDataset` no longer allows null keys in constructor (this
is a consequence of introducing generics);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* JFreeChart : a free chart library for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2000-2017, by Object Refinery Limited and Contributors.
* (C) Copyright 2000-2020, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jfreechart/index.html
*
Expand Down Expand Up @@ -39,54 +39,6 @@
* Martin Hoeller;
* John Matthews;
*
* Changes
* -------
* 21-Aug-2003 : Version 1, contributed by David Browning (for the Australian
* Institute of Marine Science);
* 01-Sep-2003 : Incorporated outlier and farout symbols for low values
* also (DG);
* 08-Sep-2003 : Changed ValueAxis API (DG);
* 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
* 07-Oct-2003 : Added renderer state (DG);
* 12-Nov-2003 : Fixed casting bug reported by Tim Bardzil (DG);
* 13-Nov-2003 : Added drawHorizontalItem() method contributed by Tim
* Bardzil (DG);
* 25-Apr-2004 : Added fillBox attribute, equals() method and added
* serialization code (DG);
* 29-Apr-2004 : Changed drawing of upper and lower shadows - see bug report
* 944011 (DG);
* 05-Nov-2004 : Modified drawItem() signature (DG);
* 09-Mar-2005 : Override getLegendItem() method so that legend item shapes
* are shown as blocks (DG);
* 20-Apr-2005 : Generate legend labels, tooltips and URLs (DG);
* 09-Jun-2005 : Updated equals() to handle GradientPaint (DG);
* ------------- JFREECHART 1.0.x ---------------------------------------------
* 12-Oct-2006 : Source reformatting and API doc updates (DG);
* 12-Oct-2006 : Fixed bug 1572478, potential NullPointerException (DG);
* 05-Feb-2006 : Added event notifications to a couple of methods (DG);
* 20-Apr-2007 : Updated getLegendItem() for renderer change (DG);
* 11-May-2007 : Added check for visibility in getLegendItem() (DG);
* 17-May-2007 : Set datasetIndex and seriesIndex in getLegendItem() (DG);
* 18-May-2007 : Set dataset and seriesKey for LegendItem (DG);
* 03-Jan-2008 : Check visibility of average marker before drawing it (DG);
* 15-Jan-2008 : Add getMaximumBarWidth() and setMaximumBarWidth()
* methods (RVdS);
* 14-Feb-2008 : Fix bar position for horizontal chart, see patch
* 1888422 (RVdS);
* 27-Mar-2008 : Boxes should use outlinePaint/Stroke settings (DG);
* 17-Jun-2008 : Apply legend shape, font and paint attributes (DG);
* 02-Oct-2008 : Check item visibility in drawItem() method (DG);
* 21-Jan-2009 : Added flags to control visibility of mean and median
* indicators (DG);
* 28-Sep-2009 : Added fireChangeEvent() to setMedianVisible (DG);
* 28-Sep-2009 : Added useOutlinePaintForWhiskers flag, see patch 2868585
* by Peter Becker (DG);
* 28-Sep-2009 : Added whiskerWidth attribute, see patch 2868608 by Peter
* Becker (DG);
* 11-Oct-2011 : applied patch #3421088 from Martin Krauskopf to fix bug (MH);
* 03-Jul-2013 : Use ParamChecks (DG);
* 18-Jul-2016 : Fix drawing issue with horizontal orientation (JM);
*
*/

package org.jfree.chart.renderer.category;
Expand Down Expand Up @@ -174,6 +126,16 @@ public class BoxAndWhiskerRenderer extends AbstractCategoryItemRenderer
*/
private boolean meanVisible;

/**
* A flag that controls whether or not the maxOutlier is visible.
*/
private boolean maxOutlierVisible;

/**
* A flag that controls whether or not the minOutlier is visible.
*/
private boolean minOutlierVisible;

/**
* A flag that, if {@code true}, causes the whiskers to be drawn
* using the outline paint for the series. The default value is
Expand All @@ -200,6 +162,8 @@ public BoxAndWhiskerRenderer() {
this.maximumBarWidth = 1.0;
this.medianVisible = true;
this.meanVisible = true;
this.minOutlierVisible = true;
this.maxOutlierVisible = true;
this.useOutlinePaintForWhiskers = false;
this.whiskerWidth = 1.0;
setDefaultLegendShape(new Rectangle2D.Double(-4.0, -4.0, 8.0, 8.0));
Expand Down Expand Up @@ -377,6 +341,72 @@ public void setMedianVisible(boolean visible) {
fireChangeEvent();
}

/**
* Returns the flag that controls whether or not the minimum outlier is
* draw for each item.
*
* @return A boolean.
*
* @see #setMinOutlierVisible(boolean)
*
* @since 1.5.2
*/
public boolean isMinOutlierVisible() {
return this.minOutlierVisible;
}

/**
* Sets the flag that controls whether or not the minimum outlier is drawn
* for each item, and sends a {@link RendererChangeEvent} to all
* registered listeners.
*
* @param visible the new flag value.
*
* @see #isMinOutlierVisible()
*
* @since 1.5.2
*/
public void setMinOutlierVisible(boolean visible) {
if (this.minOutlierVisible == visible) {
return;
}
this.minOutlierVisible = visible;
fireChangeEvent();
}

/**
* Returns the flag that controls whether or not the maximum outlier is
* draw for each item.
*
* @return A boolean.
*
* @see #setMaxOutlierVisible(boolean)
*
* @since 1.5.2
*/
public boolean isMaxOutlierVisible() {
return this.maxOutlierVisible;
}

/**
* Sets the flag that controls whether or not the maximum outlier is drawn
* for each item, and sends a {@link RendererChangeEvent} to all
* registered listeners.
*
* @param visible the new flag value.
*
* @see #isMaxOutlierVisible()
*
* @since 1.5.2
*/
public void setMaxOutlierVisible(boolean visible) {
if (this.maxOutlierVisible == visible) {
return;
}
this.maxOutlierVisible = visible;
fireChangeEvent();
}

/**
* Returns the flag that, if {@code true}, causes the whiskers to
* be drawn using the series outline paint.
Expand Down Expand Up @@ -557,8 +587,7 @@ else if (orientation == PlotOrientation.VERTICAL) {
if ((rows * columns) > 0) {
state.setBarWidth(Math.min(used / (dataset.getColumnCount()
* dataset.getRowCount()), maxWidth));
}
else {
} else {
state.setBarWidth(Math.min(used, maxWidth));
}
}
Expand Down Expand Up @@ -654,8 +683,7 @@ public void drawHorizontalItem(Graphics2D g2,
// than the category width
double offset = (categoryWidth - usedWidth) / 2;
yy = yy + offset + (row * (state.getBarWidth() + seriesGap));
}
else {
} else {
// offset the start of the box if the box width is smaller than
// the category width
double offset = (categoryWidth - state.getBarWidth()) / 2;
Expand Down Expand Up @@ -919,17 +947,14 @@ public void drawVerticalItem(Graphics2D g2, CategoryItemRendererState state,
Number maxRegular = bawDataset.getMaxRegularValue(row, column);
if (outlier > maxOutlier.doubleValue()) {
outlierListCollection.setHighFarOut(true);
}
else if (outlier < minOutlier.doubleValue()) {
} else if (outlier < minOutlier.doubleValue()) {
outlierListCollection.setLowFarOut(true);
}
else if (outlier > maxRegular.doubleValue()) {
} else if (outlier > maxRegular.doubleValue()) {
yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea,
location);
outliers.add(new Outlier(xx + state.getBarWidth() / 2.0,
yyOutlier, oRadius));
}
else if (outlier < minRegular.doubleValue()) {
} else if (outlier < minRegular.doubleValue()) {
yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea,
location);
outliers.add(new Outlier(xx + state.getBarWidth() / 2.0,
Expand All @@ -954,19 +979,18 @@ else if (outlier < minRegular.doubleValue()) {
if (list.isMultiple()) {
drawMultipleEllipse(point, state.getBarWidth(), oRadius,
g2);
}
else {
} else {
drawEllipse(point, oRadius, g2);
}
}

// draw farout indicators
if (outlierListCollection.isHighFarOut()) {
if (isMaxOutlierVisible() && outlierListCollection.isHighFarOut()) {
drawHighFarOut(aRadius / 2.0, g2,
xx + state.getBarWidth() / 2.0, maxAxisValue);
}

if (outlierListCollection.isLowFarOut()) {
if (isMinOutlierVisible() && outlierListCollection.isLowFarOut()) {
drawLowFarOut(aRadius / 2.0, g2,
xx + state.getBarWidth() / 2.0, minAxisValue);
}
Expand Down Expand Up @@ -1076,6 +1100,12 @@ public boolean equals(Object obj) {
if (this.medianVisible != that.medianVisible) {
return false;
}
if (this.minOutlierVisible != that.minOutlierVisible) {
return false;
}
if (this.maxOutlierVisible != that.maxOutlierVisible) {
return false;
}
if (this.useOutlinePaintForWhiskers
!= that.useOutlinePaintForWhiskers) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ public void testEquals() {
assertFalse(r1.equals(r2));
r2.setMedianVisible(false);
assertTrue(r1.equals(r2));

r1.setMinOutlierVisible(false);
assertFalse(r1.equals(r2));
r2.setMinOutlierVisible(false);
assertTrue(r1.equals(r2));

r1.setMaxOutlierVisible(false);
assertFalse(r1.equals(r2));
r2.setMaxOutlierVisible(false);
assertTrue(r1.equals(r2));
}

/**
Expand All @@ -128,6 +138,7 @@ public void testHashcode() {

/**
* Confirm that cloning works.
*
* @throws java.lang.CloneNotSupportedException
*/
@Test
Expand Down

0 comments on commit c1a6c13

Please sign in to comment.