![JAR search and dependency download from the Maven repository](/logo.png)
com.day.cq.graphics.chart.BarChart Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*
* Copyright 1997-2004 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.cq.graphics.chart;
import java.awt.Color;
import java.awt.Rectangle;
import com.day.cq.graphics.Graph;
import com.day.image.Font;
import com.day.image.Layer;
/**
* @author fmeschbe
*/
public class BarChart extends Chart {
public static final int BARS_TILE = 0;
public static final int BARS_CASCADE = 1;
public static final int BARS_HORIZONTAL = 2;
public static final int BARS_CANDLE = 3;
int style = 0;
int barwidth = 0;
int barspacing = 0;
int numlines = 0;
public static String getName() {
return "bar";
}
public Layer draw(Graph graph, boolean doDraw) {
// init infos
int numtitles = 0;
// get axis and force creation if not existing yet
Axis yAxis = graph.getYAxis();
Axis xAxis = graph.getXAxis();
if ((yAxis.titlepos & Axis.TITLE_POS_ABOVE) != 0)
numtitles++;
if ((yAxis.titlepos & Axis.TITLE_POS_BELOW) != 0)
numtitles++;
if (style == BARS_HORIZONTAL) {
yAxis.setType(Axis.V_AXIS);
if (yAxis.height == 0) {
yAxis.setRangescale(0);
yAxis.height = yAxis.tickdistance
* (graph.getData().numrows + numtitles);
} else if (yAxis.tickdistance == 0) {
yAxis.setRangescale(0);
yAxis.tickdistance = yAxis.height
/ (graph.getData().numrows + numtitles);
} else {
yAxis.setRangescale(yAxis.tickdistance);
}
if ((yAxis.titlepos & Axis.TITLE_POS_ABOVE) != 0) {
yAxis.setRangemin(-1);
yAxis.setRangeoffset(1);
} else {
yAxis.setRangemin(0);
yAxis.setRangeoffset(0);
}
yAxis.numticks = graph.getData().numrows;
yAxis.setRangemax(yAxis.getRangemin() + numtitles
+ graph.getData().numrows - 1);
yAxis.setRangestep(1);
yAxis.setLabelformat("%s");
} else {
yAxis.setType(Axis.Y_AXIS);
getBarMetrics(graph, graph.getMetrics(), yAxis);
// little hack if label is to be displayed above
yAxis.height = graph.getMetrics().height + 1;
yAxis.numticks = graph.getMetrics().numlines;
if (yAxis.labelalign == Axis.LABEL_ABOVE) {
yAxis.height += yAxis.tickdistance;
yAxis.numticks++;
}
yAxis.setRangemin(graph.getMetrics().bottomvalue);
yAxis.setRangemax(graph.getMetrics().topvalue);
yAxis.setRangestep(graph.getMetrics().distance);
if (yAxis.getRangescale() == 0) {
yAxis.setRangescale(graph.getMetrics().height
/ (yAxis.getRangemax() - yAxis.getRangemin()));
yAxis.numticks = (int) ((yAxis.getRangemax() - yAxis
.getRangemin()) / yAxis.getRangestep());
}
yAxis.setRangeoffset(-yAxis.getRangemin());
yAxis.setLabelformat("%." + graph.getMetrics().coma + "f");
}
if (xAxis.rangetype == Axis.TYPE_CATEG
|| xAxis.rangetype == Axis.TYPE_CATEGINV) {
int numticks = graph.getData().numcols;
if (xAxis.width == 0) {
xAxis.width = xAxis.tickdistance - numticks;
xAxis.setRangescale(0);
} else if (xAxis.tickdistance == 0) {
xAxis.tickdistance = xAxis.width / numticks;
xAxis.setRangescale(0);
} else {
xAxis.setRangescale(xAxis.tickdistance);
}
xAxis.setType(Axis.U_AXIS);
xAxis.setRangemin(0);
xAxis.setRangemax(numticks - 1);
xAxis.setRangestep(1);
xAxis.setRangeoffset(0.5);
xAxis.setLabelformat("%s");
} else {
xAxis.setType(Axis.X_AXIS);
getBarMetrics(graph, graph.getMetrics(), xAxis);
xAxis.numticks = graph.getMetrics().numlines - 1;
if (xAxis.width == 0) {
xAxis.width = graph.getMetrics().height;
xAxis.setRangescale(graph.getMetrics().scaley);
} else if (xAxis.tickdistance == 0) {
xAxis.tickdistance = xAxis.width / xAxis.numticks;
xAxis
.setRangescale(xAxis.width
/ (graph.getMetrics().topvalue - graph
.getMetrics().minvalue));
} else {
xAxis.setRangescale(graph.getMetrics().scaley);
}
xAxis.setRangemin(graph.getMetrics().minvalue);
xAxis.setRangemax(graph.getMetrics().maxvalue);
xAxis.setRangestep(graph.getMetrics().distance);
xAxis.setRangeoffset(0);
xAxis.setLabelformat("%." + graph.getMetrics().coma + "f");
}
/* build it */
Layer[] axisLayers = new Layer[2];
axisLayers[0] = graph.getYAxis().draw(graph, doDraw);
axisLayers[1] = graph.getXAxis().draw(graph, doDraw);
Layer dataLayer = drawBars(graph, doDraw);
dataLayer.merge(axisLayers);
return doDraw ? dataLayer : null;
}
public void setStyle(int style) {
if (this.style == 0)
this.style = style;
}
public void setBarwidth(int barwidth) {
if (this.barwidth == 0)
this.barwidth = barwidth;
}
public void setBarspacing(int barspacing) {
if (this.barspacing == 0)
this.barspacing = barspacing;
}
public void setNumlines(int numlines) {
if (this.numlines == 0)
this.numlines = numlines;
}
// ---------- internal
// ------------------------------------------------------
private void getBarMetrics(Graph graph, Metrics mx, Axis ax) {
Data data = graph.getData();
// init locals
int approx = this.numlines;
double maxValue = 0;
double minValue = 0;
double topValue = 0;
double botValue = 0;
// get max value
if (style == BARS_TILE) {
for (int j = 0; j < data.numcols; j++) {
double rest = 0;
for (int i = 0; i < data.numrows; i++) {
rest += data.datarows[i].samples[j];
}
if (rest > maxValue)
maxValue = rest;
}
} else {
// cascading or candle
if (style == BARS_CANDLE) {
minValue = Double.MAX_VALUE;
}
for (int j = 0; j < data.numcols; j++) {
for (int i = 0; i < data.numrows; i++) {
double rest = data.datarows[i].samples[j];
if (rest < minValue)
minValue = rest;
if (rest > maxValue)
maxValue = rest;
}
}
}
maxValue *= ax.inflate;
// get next 'nice' number, for the moment, we take a power of 10
double delta = maxValue - minValue;
if (delta == 0)
delta = 1;
double power = Math.log(delta) / Math.log(10);
if (power == Math.floor(power))
power -= 1.0;
power = Math.floor(power);
// try to improve resolution
double distance = 0;
double ac = 0;
int first = 0;
double[] factors = new double[]{0.1, 0.2, 0.25, 0.3, 0.5, 0.6, 1};
do {
for (int i = first; i < factors.length; i++) {
distance = Math.pow(10, power) * (factors[i] + ac);
topValue = Math.ceil(maxValue / distance) * distance;
if (topValue == maxValue)
topValue += distance;
botValue = Math.floor(minValue / distance) * distance;
numlines = (int) ((topValue - botValue) / distance);
if (numlines <= approx)
break;
}
ac += 1;
first = 1;
} while (numlines > approx);
//re-compute tickdistance depending on new number of lines and graph height
ax.tickdistance = graph.getExtent().height / numlines;
int height = ax.tickdistance * numlines;
double scale = height / (topValue - botValue);
int coma = 0;
double rest = distance - Math.rint(distance);
while (rest > 0.00001 && rest < 1.0 && coma < 4) {
coma++;
rest = (rest * 10.0) - Math.rint(rest * 10.0);
}
mx.height = height;
mx.coma = coma;
mx.topvalue = topValue;
mx.bottomvalue = botValue;
mx.distance = distance;
mx.scaley = scale;
mx.shifty = -(int) (topValue * scale);
mx.numlines = numlines;
mx.maxvalue = maxValue;
mx.minvalue = minValue;
}
private Layer drawBars(Graph graph, boolean doDraw) {
// don't do anything if we don't draw ...
if (!doDraw)
return null;
Axis xAxis = graph.getXAxis();
Axis yAxis = graph.getYAxis();
int w = xAxis.width;
int h = yAxis.height;
if ((yAxis.titlepos & Axis.TITLE_POS_BELOW) != 0)
h -= yAxis.getRangescale();
Layer l = graph.createLayer(true, w, h);
if ((yAxis.titlepos & Axis.TITLE_POS_ABOVE) != 0) {
// hack upper x-axis
double scale = xAxis.getRangescale();
int ypos = (xAxis.subtickto > xAxis.tickto) ? xAxis.subtickto
: xAxis.tickto;
int x, flags;
String tmp;
// ignore range type so far
double pos = xAxis.getRangemin();
for (int num = 0; num <= xAxis.numticks; num++, pos += xAxis
.getRangestep()) {
// tick ?
x = (int) ((pos + xAxis.getRangeoffset()) * scale);
// draw text
if (xAxis.labelfont != null) {
int rl = x + xAxis.labeldx;
int rt = ypos - xAxis.tickfrom - xAxis.labeldy;
tmp = String.format(xAxis.getLabelformat(), String
.valueOf(pos));
flags = 0;
if (xAxis.labelalign == Axis.LABEL_CENTER) {
flags = Font.ALIGN_CENTER;
rl -= xAxis.labelwidth / 2;
}
xAxis.labelfont.drawText(l, rl, rt, xAxis.labelwidth, 0,
tmp, xAxis.labelcolor, null, flags, xAxis.labelcs,
0);
}
;
}
}
// first draw the grid
graph.getGrid().draw(l, doDraw);
if (xAxis.getType() == Axis.U_AXIS) {
int bw = barwidth;
for (int col = (int) xAxis.getRangemin(); col <= xAxis
.getRangemax(); col += xAxis.getRangestep()) {
if (style == BARS_TILE) {
double realtop = 0.0;
int rt = h - 1;
int rb = 0;
int rl = (int) (((col + xAxis.getRangeoffset()) * xAxis
.getRangescale()) - bw / 2);
int rr = rl + bw;
for (int row = 0; row < graph.getData().numrows; row++) {
realtop += (graph.getData().datarows[row].samples[col]);
rb = rt;
rt = (h - 1)
- (int) (Math.round(realtop) * yAxis
.getRangescale());
l.setPaint(graph.getData().datarows[row].color);
l.fillRect(new Rectangle(rl, rt, rr - rl, rb - rt));
}
} else if (style == BARS_CANDLE) {
// we abuse the bar-spacing for the 2nd barwidth
int bsp = barspacing;
for (int row = 0; row < graph.getData().numrows; row += 2) {
double d0 = graph.getData().datarows[row].samples[col]
+ yAxis.getRangeoffset();
double d1 = graph.getData().datarows[row + 1].samples[col]
+ yAxis.getRangeoffset();
Color color;
int rt, rl, rb, rr;
if (d0 > d1) {
rb = h - 1 - (int) (d1 * yAxis.getRangescale());
rt = h - 1 - (int) (d0 * yAxis.getRangescale());
color = graph.getData().datarows[row + 1].color;
} else {
rb = h - 1 - (int) (d0 * yAxis.getRangescale());
rt = h - 1 - (int) (d1 * yAxis.getRangescale());
color = graph.getData().datarows[row].color;
}
if (row % 4 != 0) {
// draw thick part
rl = (int) (((col + xAxis.getRangeoffset()) * xAxis
.getRangescale()) - bw / 2);
rr = rl + bw + 1;
} else {
// draw thin part
rl = (int) (((col + xAxis.getRangeoffset()) * xAxis
.getRangescale()) - bsp / 2);
rr = rl + bsp + 1;
}
l.setPaint(color);
l.fillRect(new Rectangle(rl, rt, rr - rl, rb - rt));
}
} else {
// cascading
int zeroline = (int) (h - 1 - yAxis.getRangeoffset()
* yAxis.getRangescale());
int bsp = barspacing;
int rr = (int) (((col + xAxis.getRangeoffset()) * xAxis
.getRangescale()) - (bw * graph.getData().numrows + bsp
* (graph.getData().numrows - 1)) / 2)
- bsp;
for (int row = 0; row < graph.getData().numrows; row++) {
double d = graph.getData().datarows[row].samples[col];
int rl = rr + bsp;
rr = rl + bw;
int rb, rt;
if (d >= 0) {
rb = zeroline;
rt = zeroline - (int) (d * yAxis.getRangescale());
} else {
rt = zeroline;
rb = zeroline - (int) (d * yAxis.getRangescale());
}
l.setPaint(graph.getData().datarows[row].color);
l.fillRect(new Rectangle(rl, rt, rr - rl, rb - rt));
}
}
}
l.setY(-h);
} else {
//
// NOT SUPPORTED YET
//
if (style == BARS_HORIZONTAL) {
int bw = barwidth;
for (int col = 0; col < graph.getData().numrows; col++) {
int y = (int) (yAxis.tickpos[col] + yAxis.getRangescale() / 2);
int rt = y - bw / 2;
int rb = y + bw / 2;
int rl = 0;
double d = graph.getData().datarows[col].samples[0];
int rr = (int) (d * xAxis.getRangescale());
l.setPaint(graph.getData().datarows[0].color);
l.fillRect(new Rectangle(rl, rt, rr - rl, rb - rt));
}
l.setX(1);
l.setY(-h - 1);
}
}
return l;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy