| Method from org.jfree.chart.renderer.category.BarRenderer Detail: |
protected double[] calculateBarL0L1(double value) {
double lclip = getLowerClip();
double uclip = getUpperClip();
double barLow = Math.min(this.base, value);
double barHigh = Math.max(this.base, value);
if (barHigh < lclip) { // bar is not visible
return null;
}
if (barLow > uclip) { // bar is not visible
return null;
}
barLow = Math.max(barLow, lclip);
barHigh = Math.min(barHigh, uclip);
return new double[] {barLow, barHigh};
}
Calculates the coordinates for the length of a single bar. |
protected double calculateBarW0(CategoryPlot plot,
PlotOrientation orientation,
Rectangle2D dataArea,
CategoryAxis domainAxis,
CategoryItemRendererState state,
int row,
int column) {
// calculate bar width...
double space = 0.0;
if (orientation == PlotOrientation.HORIZONTAL) {
space = dataArea.getHeight();
}
else {
space = dataArea.getWidth();
}
double barW0 = domainAxis.getCategoryStart(column, getColumnCount(),
dataArea, plot.getDomainAxisEdge());
int seriesCount = getRowCount();
int categoryCount = getColumnCount();
if (seriesCount > 1) {
double seriesGap = space * getItemMargin()
/ (categoryCount * (seriesCount - 1));
double seriesW = calculateSeriesWidth(space, domainAxis,
categoryCount, seriesCount);
barW0 = barW0 + row * (seriesW + seriesGap)
+ (seriesW / 2.0) - (state.getBarWidth() / 2.0);
}
else {
barW0 = domainAxis.getCategoryMiddle(column, getColumnCount(),
dataArea, plot.getDomainAxisEdge()) - state.getBarWidth()
/ 2.0;
}
return barW0;
}
Calculates the coordinate of the first "side" of a bar. This will be
the minimum x-coordinate for a vertical bar, and the minimum
y-coordinate for a horizontal bar. |
protected void calculateBarWidth(CategoryPlot plot,
Rectangle2D dataArea,
int rendererIndex,
CategoryItemRendererState state) {
CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex);
CategoryDataset dataset = plot.getDataset(rendererIndex);
if (dataset != null) {
int columns = dataset.getColumnCount();
int rows = dataset.getRowCount();
double space = 0.0;
PlotOrientation orientation = plot.getOrientation();
if (orientation == PlotOrientation.HORIZONTAL) {
space = dataArea.getHeight();
}
else if (orientation == PlotOrientation.VERTICAL) {
space = dataArea.getWidth();
}
double maxWidth = space * getMaximumBarWidth();
double categoryMargin = 0.0;
double currentItemMargin = 0.0;
if (columns > 1) {
categoryMargin = domainAxis.getCategoryMargin();
}
if (rows > 1) {
currentItemMargin = getItemMargin();
}
double used = space * (1 - domainAxis.getLowerMargin()
- domainAxis.getUpperMargin()
- categoryMargin - currentItemMargin);
if ((rows * columns) > 0) {
state.setBarWidth(Math.min(used / (rows * columns), maxWidth));
}
else {
state.setBarWidth(Math.min(used, maxWidth));
}
}
}
Calculates the bar width and stores it in the renderer state. |
protected double calculateSeriesWidth(double space,
CategoryAxis axis,
int categories,
int series) {
double factor = 1.0 - getItemMargin() - axis.getLowerMargin()
- axis.getUpperMargin();
if (categories > 1) {
factor = factor - axis.getCategoryMargin();
}
return (space * factor) / (categories * series);
}
Calculates the available space for each series. |
public void drawItem(Graphics2D g2,
CategoryItemRendererState state,
Rectangle2D dataArea,
CategoryPlot plot,
CategoryAxis domainAxis,
ValueAxis rangeAxis,
CategoryDataset dataset,
int row,
int column,
int pass) {
// nothing is drawn for null values...
Number dataValue = dataset.getValue(row, column);
if (dataValue == null) {
return;
}
double value = dataValue.doubleValue();
PlotOrientation orientation = plot.getOrientation();
double barW0 = calculateBarW0(plot, orientation, dataArea, domainAxis,
state, row, column);
double[] barL0L1 = calculateBarL0L1(value);
if (barL0L1 == null) {
return; // the bar is not visible
}
RectangleEdge edge = plot.getRangeAxisEdge();
double transL0 = rangeAxis.valueToJava2D(barL0L1[0], dataArea, edge);
double transL1 = rangeAxis.valueToJava2D(barL0L1[1], dataArea, edge);
// in the following code, barL0 is (in Java2D coordinates) the LEFT
// end of the bar for a horizontal bar chart, and the TOP end of the
// bar for a vertical bar chart. Whether this is the BASE of the bar
// or not depends also on (a) whether the data value is 'negative'
// relative to the base value and (b) whether or not the range axis is
// inverted. This only matters if/when we apply the minimumBarLength
// attribute, because we should extend the non-base end of the bar
boolean positive = (value >= this.base);
boolean inverted = rangeAxis.isInverted();
double barL0 = Math.min(transL0, transL1);
double barLength = Math.abs(transL1 - transL0);
double barLengthAdj = 0.0;
if (barLength > 0.0 && barLength < getMinimumBarLength()) {
barLengthAdj = getMinimumBarLength() - barLength;
}
double barL0Adj = 0.0;
if (orientation == PlotOrientation.HORIZONTAL) {
if (positive && inverted || !positive && !inverted) {
barL0Adj = barLengthAdj;
}
}
else {
if (positive && !inverted || !positive && inverted) {
barL0Adj = barLengthAdj;
}
}
// draw the bar...
Rectangle2D bar = null;
if (orientation == PlotOrientation.HORIZONTAL) {
bar = new Rectangle2D.Double(barL0 - barL0Adj, barW0,
barLength + barLengthAdj, state.getBarWidth());
}
else {
bar = new Rectangle2D.Double(barW0, barL0 - barL0Adj,
state.getBarWidth(), barLength + barLengthAdj);
}
Paint itemPaint = getItemPaint(row, column);
GradientPaintTransformer t = getGradientPaintTransformer();
if (t != null && itemPaint instanceof GradientPaint) {
itemPaint = t.transform((GradientPaint) itemPaint, bar);
}
g2.setPaint(itemPaint);
g2.fill(bar);
// draw the outline...
if (isDrawBarOutline()
&& state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
Stroke stroke = getItemOutlineStroke(row, column);
Paint paint = getItemOutlinePaint(row, column);
if (stroke != null && paint != null) {
g2.setStroke(stroke);
g2.setPaint(paint);
g2.draw(bar);
}
}
CategoryItemLabelGenerator generator
= getItemLabelGenerator(row, column);
if (generator != null && isItemLabelVisible(row, column)) {
drawItemLabel(g2, dataset, row, column, plot, generator, bar,
(value < 0.0));
}
// add an item entity, if this information is being collected
EntityCollection entities = state.getEntityCollection();
if (entities != null) {
addItemEntity(entities, dataset, row, column, bar);
}
}
Draws the bar for a single (series, category) data item. |
protected void drawItemLabel(Graphics2D g2,
CategoryDataset data,
int row,
int column,
CategoryPlot plot,
CategoryItemLabelGenerator generator,
Rectangle2D bar,
boolean negative) {
String label = generator.generateLabel(data, row, column);
if (label == null) {
return; // nothing to do
}
Font labelFont = getItemLabelFont(row, column);
g2.setFont(labelFont);
Paint paint = getItemLabelPaint(row, column);
g2.setPaint(paint);
// find out where to place the label...
ItemLabelPosition position = null;
if (!negative) {
position = getPositiveItemLabelPosition(row, column);
}
else {
position = getNegativeItemLabelPosition(row, column);
}
// work out the label anchor point...
Point2D anchorPoint = calculateLabelAnchorPoint(
position.getItemLabelAnchor(), bar, plot.getOrientation());
if (isInternalAnchor(position.getItemLabelAnchor())) {
Shape bounds = TextUtilities.calculateRotatedStringBounds(label,
g2, (float) anchorPoint.getX(), (float) anchorPoint.getY(),
position.getTextAnchor(), position.getAngle(),
position.getRotationAnchor());
if (bounds != null) {
if (!bar.contains(bounds.getBounds2D())) {
if (!negative) {
position = getPositiveItemLabelPositionFallback();
}
else {
position = getNegativeItemLabelPositionFallback();
}
if (position != null) {
anchorPoint = calculateLabelAnchorPoint(
position.getItemLabelAnchor(), bar,
plot.getOrientation());
}
}
}
}
if (position != null) {
TextUtilities.drawRotatedString(label, g2,
(float) anchorPoint.getX(), (float) anchorPoint.getY(),
position.getTextAnchor(), position.getAngle(),
position.getRotationAnchor());
}
}
Draws an item label. This method is overridden so that the bar can be
used to calculate the label anchor point. |
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof BarRenderer)) {
return false;
}
if (!super.equals(obj)) {
return false;
}
BarRenderer that = (BarRenderer) obj;
if (this.base != that.base) {
return false;
}
if (this.itemMargin != that.itemMargin) {
return false;
}
if (this.drawBarOutline != that.drawBarOutline) {
return false;
}
if (this.maximumBarWidth != that.maximumBarWidth) {
return false;
}
if (this.minimumBarLength != that.minimumBarLength) {
return false;
}
if (!ObjectUtilities.equal(this.gradientPaintTransformer,
that.gradientPaintTransformer)) {
return false;
}
if (!ObjectUtilities.equal(this.positiveItemLabelPositionFallback,
that.positiveItemLabelPositionFallback)) {
return false;
}
if (!ObjectUtilities.equal(this.negativeItemLabelPositionFallback,
that.negativeItemLabelPositionFallback)) {
return false;
}
return true;
}
Tests this instance for equality with an arbitrary object. |
public Range findRangeBounds(CategoryDataset dataset) {
Range result = DatasetUtilities.findRangeBounds(dataset);
if (result != null) {
if (this.includeBaseInRange) {
result = Range.expandToInclude(result, this.base);
}
}
return result;
}
Returns the range of values the renderer requires to display all the
items from the specified dataset. This takes into account the range
of values in the dataset, plus the flag that determines whether or not
the base value for the bars should be included in the range. |
public double getBase() {
return this.base;
}
Returns the base value for the bars. The default value is
0.0. |
public GradientPaintTransformer getGradientPaintTransformer() {
return this.gradientPaintTransformer;
}
Returns the gradient paint transformer (an object used to transform
gradient paint objects to fit each bar). |
public boolean getIncludeBaseInRange() {
return this.includeBaseInRange;
}
|
public double getItemMargin() {
return this.itemMargin;
}
Returns the item margin as a percentage of the available space for all
bars. |
public LegendItem getLegendItem(int datasetIndex,
int series) {
CategoryPlot cp = getPlot();
if (cp == null) {
return null;
}
// check that a legend item needs to be displayed...
if (!isSeriesVisible(series) || !isSeriesVisibleInLegend(series)) {
return null;
}
CategoryDataset dataset = cp.getDataset(datasetIndex);
String label = getLegendItemLabelGenerator().generateLabel(dataset,
series);
String description = label;
String toolTipText = null;
if (getLegendItemToolTipGenerator() != null) {
toolTipText = getLegendItemToolTipGenerator().generateLabel(
dataset, series);
}
String urlText = null;
if (getLegendItemURLGenerator() != null) {
urlText = getLegendItemURLGenerator().generateLabel(dataset,
series);
}
Shape shape = new Rectangle2D.Double(-4.0, -4.0, 8.0, 8.0);
Paint paint = lookupSeriesPaint(series);
Paint outlinePaint = lookupSeriesOutlinePaint(series);
Stroke outlineStroke = lookupSeriesOutlineStroke(series);
LegendItem result = new LegendItem(label, description, toolTipText,
urlText, true, shape, true, paint, isDrawBarOutline(),
outlinePaint, outlineStroke, false, new Line2D.Float(),
new BasicStroke(1.0f), Color.black);
result.setDataset(dataset);
result.setDatasetIndex(datasetIndex);
result.setSeriesKey(dataset.getRowKey(series));
result.setSeriesIndex(series);
if (this.gradientPaintTransformer != null) {
result.setFillPaintTransformer(this.gradientPaintTransformer);
}
return result;
}
Returns a legend item for a series. |
public double getLowerClip() {
// TODO: this attribute should be transferred to the renderer state.
return this.lowerClip;
}
Returns the lower clip value. This value is recalculated in the
initialise() method. |
public double getMaximumBarWidth() {
return this.maximumBarWidth;
}
Returns the maximum bar width, as a percentage of the available drawing
space. |
public double getMinimumBarLength() {
return this.minimumBarLength;
}
Returns the minimum bar length (in Java2D units). The default value is
0.0. |
public ItemLabelPosition getNegativeItemLabelPositionFallback() {
return this.negativeItemLabelPositionFallback;
}
Returns the fallback position for negative item labels that don't fit
within a bar. |
public ItemLabelPosition getPositiveItemLabelPositionFallback() {
return this.positiveItemLabelPositionFallback;
}
Returns the fallback position for positive item labels that don't fit
within a bar. |
public double getUpperClip() {
// TODO: this attribute should be transferred to the renderer state.
return this.upperClip;
}
Returns the upper clip value. This value is recalculated in the
initialise() method. |
public CategoryItemRendererState initialise(Graphics2D g2,
Rectangle2D dataArea,
CategoryPlot plot,
int rendererIndex,
PlotRenderingInfo info) {
CategoryItemRendererState state = super.initialise(g2, dataArea, plot,
rendererIndex, info);
// get the clipping values...
ValueAxis rangeAxis = plot.getRangeAxisForDataset(rendererIndex);
this.lowerClip = rangeAxis.getRange().getLowerBound();
this.upperClip = rangeAxis.getRange().getUpperBound();
// calculate the bar width
calculateBarWidth(plot, dataArea, rendererIndex, state);
return state;
}
Initialises the renderer and returns a state object that will be passed
to subsequent calls to the drawItem method. This method gets called
once at the start of the process of drawing a chart. |
public boolean isDrawBarOutline() {
return this.drawBarOutline;
}
Returns a flag that controls whether or not bar outlines are drawn. |
public void setBase(double base) {
this.base = base;
fireChangeEvent();
}
|
public void setDrawBarOutline(boolean draw) {
this.drawBarOutline = draw;
fireChangeEvent();
}
Sets the flag that controls whether or not bar outlines are drawn and
sends a RendererChangeEvent to all registered listeners. |
public void setGradientPaintTransformer(GradientPaintTransformer transformer) {
this.gradientPaintTransformer = transformer;
fireChangeEvent();
}
Sets the gradient paint transformer and sends a
RendererChangeEvent to all registered listeners. |
public void setIncludeBaseInRange(boolean include) {
if (this.includeBaseInRange != include) {
this.includeBaseInRange = include;
fireChangeEvent();
}
}
|
public void setItemMargin(double percent) {
this.itemMargin = percent;
fireChangeEvent();
}
Sets the item margin and sends a RendererChangeEvent to all
registered listeners. The value is expressed as a percentage of the
available width for plotting all the bars, with the resulting amount to
be distributed between all the bars evenly. |
public void setMaximumBarWidth(double percent) {
this.maximumBarWidth = percent;
fireChangeEvent();
}
Sets the maximum bar width, which is specified as a percentage of the
available space for all bars, and sends a RendererChangeEvent to
all registered listeners. |
public void setMinimumBarLength(double min) {
if (min < 0.0) {
throw new IllegalArgumentException("Requires 'min' >= 0.0");
}
this.minimumBarLength = min;
fireChangeEvent();
}
Sets the minimum bar length and sends a RendererChangeEvent to
all registered listeners. The minimum bar length is specified in Java2D
units, and can be used to prevent bars that represent very small data
values from disappearing when drawn on the screen. Typically you would
set this to (say) 0.5 or 1.0 Java 2D units. Use this attribute with
caution, however, because setting it to a non-zero value will
artificially increase the length of bars representing small values,
which may misrepresent your data. |
public void setNegativeItemLabelPositionFallback(ItemLabelPosition position) {
this.negativeItemLabelPositionFallback = position;
fireChangeEvent();
}
Sets the fallback position for negative item labels that don't fit
within a bar, and sends a RendererChangeEvent to all registered
listeners. |
public void setPositiveItemLabelPositionFallback(ItemLabelPosition position) {
this.positiveItemLabelPositionFallback = position;
fireChangeEvent();
}
Sets the fallback position for positive item labels that don't fit
within a bar, and sends a RendererChangeEvent to all registered
listeners. |