use of org.jfree.chart.text.TextAnchor in project ES-LEI-2Sem-2022-Grupo-1 by tmrbo-iscte.
the class CyclicNumberAxis method refreshVerticalTicks.
/**
* Builds a list of ticks for the axis. This method is called when the
* axis is at the left or right of the chart (so the axis is "vertical").
*
* @param g2 the graphics device.
* @param dataArea the data area.
* @param edge the edge.
*
* @return A list of ticks.
*/
protected List refreshVerticalTicks(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new java.util.ArrayList();
result.clear();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection()) {
selectAutoTickUnit(g2, dataArea, edge);
}
double unit = getTickUnit().getSize();
double cycleBound = getCycleBound();
double currentTickValue = Math.ceil(cycleBound / unit) * unit;
double upperValue = getRange().getUpperBound();
boolean cycled = false;
boolean boundMapping = this.boundMappedToLastCycle;
this.boundMappedToLastCycle = true;
NumberTick lastTick = null;
float lastY = 0.0f;
if (upperValue == cycleBound) {
currentTickValue = calculateLowestVisibleTickValue();
cycled = true;
this.boundMappedToLastCycle = true;
}
while (currentTickValue <= upperValue) {
// Cycle when necessary
boolean cyclenow = false;
if ((currentTickValue + unit > upperValue) && !cycled) {
cyclenow = true;
}
double yy = valueToJava2D(currentTickValue, dataArea, edge);
String tickLabel;
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = getTickUnit().valueToString(currentTickValue);
}
float y = (float) yy;
TextAnchor anchor;
TextAnchor rotationAnchor;
double angle = 0.0;
if (isVerticalTickLabels()) {
if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.BOTTOM_CENTER;
if ((lastTick != null) && (lastY == y) && (currentTickValue != cycleBound)) {
anchor = isInverted() ? TextAnchor.BOTTOM_LEFT : TextAnchor.BOTTOM_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.BOTTOM_LEFT;
}
rotationAnchor = anchor;
angle = -Math.PI / 2.0;
} else {
anchor = TextAnchor.BOTTOM_CENTER;
if ((lastTick != null) && (lastY == y) && (currentTickValue != cycleBound)) {
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.BOTTOM_LEFT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.BOTTOM_LEFT : TextAnchor.BOTTOM_RIGHT;
}
rotationAnchor = anchor;
angle = Math.PI / 2.0;
}
} else {
if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.CENTER_RIGHT;
if ((lastTick != null) && (lastY == y) && (currentTickValue != cycleBound)) {
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.TOP_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.TOP_RIGHT : TextAnchor.BOTTOM_RIGHT;
}
rotationAnchor = anchor;
} else {
anchor = TextAnchor.CENTER_LEFT;
if ((lastTick != null) && (lastY == y) && (currentTickValue != cycleBound)) {
anchor = isInverted() ? TextAnchor.BOTTOM_LEFT : TextAnchor.TOP_LEFT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.TOP_LEFT : TextAnchor.BOTTOM_LEFT;
}
rotationAnchor = anchor;
}
}
CycleBoundTick tick = new CycleBoundTick(this.boundMappedToLastCycle, currentTickValue, tickLabel, anchor, rotationAnchor, angle);
if (currentTickValue == cycleBound) {
this.internalMarkerCycleBoundTick = tick;
}
result.add(tick);
lastTick = tick;
lastY = y;
if (currentTickValue == cycleBound) {
this.internalMarkerCycleBoundTick = tick;
}
currentTickValue += unit;
if (cyclenow) {
currentTickValue = calculateLowestVisibleTickValue();
upperValue = cycleBound;
cycled = true;
this.boundMappedToLastCycle = false;
}
}
this.boundMappedToLastCycle = boundMapping;
return result;
}
use of org.jfree.chart.text.TextAnchor in project ES-LEI-2Sem-2022-Grupo-1 by tmrbo-iscte.
the class CyclicNumberAxis method refreshTicksHorizontal.
/**
* Builds a list of ticks for the axis. This method is called when the
* axis is at the top or bottom of the chart (so the axis is "horizontal").
*
* @param g2 the graphics device.
* @param dataArea the data area.
* @param edge the edge.
*
* @return A list of ticks.
*/
@Override
protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new java.util.ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection()) {
selectAutoTickUnit(g2, dataArea, edge);
}
double unit = getTickUnit().getSize();
double cycleBound = getCycleBound();
double currentTickValue = Math.ceil(cycleBound / unit) * unit;
double upperValue = getRange().getUpperBound();
boolean cycled = false;
boolean boundMapping = this.boundMappedToLastCycle;
this.boundMappedToLastCycle = false;
CycleBoundTick lastTick = null;
float lastX = 0.0f;
if (upperValue == cycleBound) {
currentTickValue = calculateLowestVisibleTickValue();
cycled = true;
this.boundMappedToLastCycle = true;
}
while (currentTickValue <= upperValue) {
// Cycle when necessary
boolean cyclenow = false;
if ((currentTickValue + unit > upperValue) && !cycled) {
cyclenow = true;
}
double xx = valueToJava2D(currentTickValue, dataArea, edge);
String tickLabel;
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = getTickUnit().valueToString(currentTickValue);
}
float x = (float) xx;
TextAnchor anchor;
TextAnchor rotationAnchor;
double angle = 0.0;
if (isVerticalTickLabels()) {
if (edge == RectangleEdge.TOP) {
angle = Math.PI / 2.0;
} else {
angle = -Math.PI / 2.0;
}
anchor = TextAnchor.CENTER_RIGHT;
// If tick overlap when cycling, update last tick too
if ((lastTick != null) && (lastX == x) && (currentTickValue != cycleBound)) {
anchor = isInverted() ? TextAnchor.TOP_RIGHT : TextAnchor.BOTTOM_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.TOP_RIGHT;
}
rotationAnchor = anchor;
} else {
if (edge == RectangleEdge.TOP) {
anchor = TextAnchor.BOTTOM_CENTER;
if ((lastTick != null) && (lastX == x) && (currentTickValue != cycleBound)) {
anchor = isInverted() ? TextAnchor.BOTTOM_LEFT : TextAnchor.BOTTOM_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.BOTTOM_LEFT;
}
rotationAnchor = anchor;
} else {
anchor = TextAnchor.TOP_CENTER;
if ((lastTick != null) && (lastX == x) && (currentTickValue != cycleBound)) {
anchor = isInverted() ? TextAnchor.TOP_LEFT : TextAnchor.TOP_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.TOP_RIGHT : TextAnchor.TOP_LEFT;
}
rotationAnchor = anchor;
}
}
CycleBoundTick tick = new CycleBoundTick(this.boundMappedToLastCycle, currentTickValue, tickLabel, anchor, rotationAnchor, angle);
if (currentTickValue == cycleBound) {
this.internalMarkerCycleBoundTick = tick;
}
result.add(tick);
lastTick = tick;
lastX = x;
currentTickValue += unit;
if (cyclenow) {
currentTickValue = calculateLowestVisibleTickValue();
upperValue = cycleBound;
cycled = true;
this.boundMappedToLastCycle = true;
}
}
this.boundMappedToLastCycle = boundMapping;
return result;
}
use of org.jfree.chart.text.TextAnchor in project ES-LEI-2Sem-2022-Grupo-1 by tmrbo-iscte.
the class CrosshairOverlay method drawHorizontalCrosshair.
/**
* Draws a crosshair horizontally across the plot.
*
* @param g2 the graphics target.
* @param dataArea the data area.
* @param y the y-value in Java2D space.
* @param crosshair the crosshair.
*/
protected void drawHorizontalCrosshair(Graphics2D g2, Rectangle2D dataArea, double y, Crosshair crosshair) {
if (y >= dataArea.getMinY() && y <= dataArea.getMaxY()) {
Line2D line = new Line2D.Double(dataArea.getMinX(), y, dataArea.getMaxX(), y);
Paint savedPaint = g2.getPaint();
Stroke savedStroke = g2.getStroke();
g2.setPaint(crosshair.getPaint());
g2.setStroke(crosshair.getStroke());
g2.draw(line);
if (crosshair.isLabelVisible()) {
String label = crosshair.getLabelGenerator().generateLabel(crosshair);
if (label != null && !label.isEmpty()) {
Font savedFont = g2.getFont();
g2.setFont(crosshair.getLabelFont());
RectangleAnchor anchor = crosshair.getLabelAnchor();
Point2D pt = calculateLabelPoint(line, anchor, crosshair.getLabelXOffset(), crosshair.getLabelYOffset());
float xx = (float) pt.getX();
float yy = (float) pt.getY();
TextAnchor alignPt = textAlignPtForLabelAnchorH(anchor);
Shape hotspot = TextUtils.calculateRotatedStringBounds(label, g2, xx, yy, alignPt, 0.0, TextAnchor.CENTER);
if (!dataArea.contains(hotspot.getBounds2D())) {
anchor = flipAnchorV(anchor);
pt = calculateLabelPoint(line, anchor, crosshair.getLabelXOffset(), crosshair.getLabelYOffset());
xx = (float) pt.getX();
yy = (float) pt.getY();
alignPt = textAlignPtForLabelAnchorH(anchor);
hotspot = TextUtils.calculateRotatedStringBounds(label, g2, xx, yy, alignPt, 0.0, TextAnchor.CENTER);
}
g2.setPaint(crosshair.getLabelBackgroundPaint());
g2.fill(hotspot);
if (crosshair.isLabelOutlineVisible()) {
g2.setPaint(crosshair.getLabelOutlinePaint());
g2.setStroke(crosshair.getLabelOutlineStroke());
g2.draw(hotspot);
}
g2.setPaint(crosshair.getLabelPaint());
TextUtils.drawAlignedString(label, g2, xx, yy, alignPt);
g2.setFont(savedFont);
}
}
g2.setPaint(savedPaint);
g2.setStroke(savedStroke);
}
}
use of org.jfree.chart.text.TextAnchor in project ES-LEI-2Sem-2022-Grupo-1 by tmrbo-iscte.
the class SymbolAxis method refreshTicksVertical.
/**
* Calculates the positions of the tick labels for the axis, storing the
* results in the tick label list (ready for drawing).
*
* @param g2 the graphics device.
* @param dataArea the area in which the plot should be drawn.
* @param edge the location of the axis.
*
* @return The ticks.
*/
@Override
protected List refreshTicksVertical(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = new java.util.ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
double size = getTickUnit().getSize();
int count = calculateVisibleTickCount();
double lowestTickValue = calculateLowestVisibleTickValue();
double previousDrawnTickLabelPos = 0.0;
double previousDrawnTickLabelLength = 0.0;
if (count <= ValueAxis.MAXIMUM_TICK_COUNT) {
for (int i = 0; i < count; i++) {
double currentTickValue = lowestTickValue + (i * size);
double yy = valueToJava2D(currentTickValue, dataArea, edge);
String tickLabel;
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = valueToString(currentTickValue);
}
// avoid to draw overlapping tick labels
Rectangle2D bounds = TextUtils.getTextBounds(tickLabel, g2, g2.getFontMetrics());
double tickLabelLength = isVerticalTickLabels() ? bounds.getWidth() : bounds.getHeight();
boolean tickLabelsOverlapping = false;
if (i > 0) {
double avgTickLabelLength = (previousDrawnTickLabelLength + tickLabelLength) / 2.0;
if (Math.abs(yy - previousDrawnTickLabelPos) < avgTickLabelLength) {
tickLabelsOverlapping = true;
}
}
if (tickLabelsOverlapping) {
// don't draw this tick label
tickLabel = "";
} else {
// remember these values for next comparison
previousDrawnTickLabelPos = yy;
previousDrawnTickLabelLength = tickLabelLength;
}
TextAnchor anchor;
TextAnchor rotationAnchor;
double angle = 0.0;
if (isVerticalTickLabels()) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
if (edge == RectangleEdge.LEFT) {
angle = -Math.PI / 2.0;
} else {
angle = Math.PI / 2.0;
}
} else {
if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
} else {
anchor = TextAnchor.CENTER_LEFT;
rotationAnchor = TextAnchor.CENTER_LEFT;
}
}
Tick tick = new NumberTick(currentTickValue, tickLabel, anchor, rotationAnchor, angle);
ticks.add(tick);
}
}
return ticks;
}
use of org.jfree.chart.text.TextAnchor in project ES-LEI-2Sem-2022-Grupo-1 by tmrbo-iscte.
the class DateTickTest method testHashCode.
/**
* Two objects that are equal are required to return the same hashCode.
*/
@Test
public void testHashCode() {
Date d1 = new Date(0L);
String l1 = "Label 1";
TextAnchor ta1 = TextAnchor.CENTER;
DateTick t1 = new DateTick(d1, l1, ta1, ta1, Math.PI / 2.0);
DateTick t2 = new DateTick(d1, l1, ta1, ta1, Math.PI / 2.0);
assertEquals(t1, t2);
int h1 = t1.hashCode();
int h2 = t2.hashCode();
assertEquals(h1, h2);
}
Aggregations