Search in sources :

Example 6 with TextAnchor

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;
}
Also used : TextAnchor(org.jfree.chart.text.TextAnchor) List(java.util.List) Font(java.awt.Font) NumberFormat(java.text.NumberFormat)

Example 7 with TextAnchor

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;
}
Also used : TextAnchor(org.jfree.chart.text.TextAnchor) List(java.util.List) Font(java.awt.Font) NumberFormat(java.text.NumberFormat)

Example 8 with TextAnchor

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);
    }
}
Also used : Stroke(java.awt.Stroke) TextAnchor(org.jfree.chart.text.TextAnchor) Shape(java.awt.Shape) Point2D(java.awt.geom.Point2D) RectangleAnchor(org.jfree.chart.api.RectangleAnchor) Paint(java.awt.Paint) Line2D(java.awt.geom.Line2D) Font(java.awt.Font)

Example 9 with TextAnchor

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;
}
Also used : TextAnchor(org.jfree.chart.text.TextAnchor) Rectangle2D(java.awt.geom.Rectangle2D) Font(java.awt.Font) Paint(java.awt.Paint) List(java.util.List) NumberFormat(java.text.NumberFormat)

Example 10 with TextAnchor

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);
}
Also used : TextAnchor(org.jfree.chart.text.TextAnchor) Date(java.util.Date) Test(org.junit.jupiter.api.Test)

Aggregations

TextAnchor (org.jfree.chart.text.TextAnchor)23 Font (java.awt.Font)13 List (java.util.List)10 NumberFormat (java.text.NumberFormat)7 Paint (java.awt.Paint)5 Rectangle2D (java.awt.geom.Rectangle2D)5 ArrayList (java.util.ArrayList)5 Date (java.util.Date)5 Shape (java.awt.Shape)4 Test (org.junit.jupiter.api.Test)4 Line2D (java.awt.geom.Line2D)3 DateFormat (java.text.DateFormat)3 SimpleDateFormat (java.text.SimpleDateFormat)3 Range (org.jfree.data.Range)3 FontMetrics (java.awt.FontMetrics)2 Stroke (java.awt.Stroke)2 AffineTransform (java.awt.geom.AffineTransform)2 Point2D (java.awt.geom.Point2D)2 RectangleAnchor (org.jfree.chart.api.RectangleAnchor)2 RectangleInsets (org.jfree.chart.api.RectangleInsets)2