dateaxis.java

来自「JfreeChart 常用图表例子」· Java 代码 · 共 1,787 行 · 第 1/5 页

JAVA
1,787
字号
                DateTickUnit.MINUTE, 20, DateTickUnit.MINUTE, 5, f3            )        );        units.add(            new DateTickUnit(                DateTickUnit.MINUTE, 30, DateTickUnit.MINUTE, 5, f3            )        );        // hours        units.add(            new DateTickUnit(DateTickUnit.HOUR, 1, DateTickUnit.MINUTE, 5, f3)        );        units.add(            new DateTickUnit(DateTickUnit.HOUR, 2, DateTickUnit.MINUTE, 10, f3)        );        units.add(            new DateTickUnit(DateTickUnit.HOUR, 4, DateTickUnit.MINUTE, 30, f3)        );        units.add(            new DateTickUnit(DateTickUnit.HOUR, 6, DateTickUnit.HOUR, 1, f3)        );        units.add(            new DateTickUnit(DateTickUnit.HOUR, 12, DateTickUnit.HOUR, 1, f4)        );        // days        units.add(            new DateTickUnit(DateTickUnit.DAY, 1, DateTickUnit.HOUR, 1, f5)        );        units.add(            new DateTickUnit(DateTickUnit.DAY, 2, DateTickUnit.HOUR, 1, f5)        );        units.add(            new DateTickUnit(DateTickUnit.DAY, 7, DateTickUnit.DAY, 1, f5)        );        units.add(            new DateTickUnit(DateTickUnit.DAY, 15, DateTickUnit.DAY, 1, f5)        );        // months        units.add(            new DateTickUnit(DateTickUnit.MONTH, 1, DateTickUnit.DAY, 1, f6)        );        units.add(            new DateTickUnit(DateTickUnit.MONTH, 2, DateTickUnit.DAY, 1, f6)        );        units.add(            new DateTickUnit(DateTickUnit.MONTH, 3, DateTickUnit.MONTH, 1, f6)        );        units.add(            new DateTickUnit(DateTickUnit.MONTH, 4,  DateTickUnit.MONTH, 1, f6)        );        units.add(            new DateTickUnit(DateTickUnit.MONTH, 6,  DateTickUnit.MONTH, 1, f6)        );        // years        units.add(            new DateTickUnit(DateTickUnit.YEAR, 1,  DateTickUnit.MONTH, 1, f7)        );        units.add(            new DateTickUnit(DateTickUnit.YEAR, 2,  DateTickUnit.MONTH, 3, f7)        );        units.add(            new DateTickUnit(DateTickUnit.YEAR, 5,  DateTickUnit.YEAR, 1, f7)        );        units.add(            new DateTickUnit(DateTickUnit.YEAR, 10,  DateTickUnit.YEAR, 1, f7)        );        units.add(            new DateTickUnit(DateTickUnit.YEAR, 25, DateTickUnit.YEAR, 5, f7)        );        units.add(            new DateTickUnit(DateTickUnit.YEAR, 50, DateTickUnit.YEAR, 10, f7)        );        units.add(            new DateTickUnit(DateTickUnit.YEAR, 100, DateTickUnit.YEAR, 20, f7)        );        return units;    }    /**     * Rescales the axis to ensure that all data is visible.     */    protected void autoAdjustRange() {        Plot plot = getPlot();        if (plot == null) {            return;  // no plot, no data        }        if (plot instanceof ValueAxisPlot) {            ValueAxisPlot vap = (ValueAxisPlot) plot;            Range r = vap.getDataRange(this);            if (r == null) {                if (this.timeline instanceof SegmentedTimeline) {                     //Timeline hasn't method getStartTime()                    r = new DateRange(                        ((SegmentedTimeline) this.timeline).getStartTime(),                        ((SegmentedTimeline) this.timeline).getStartTime() + 1                    );                }                 else {                    r = new DateRange();                }            }            long upper = this.timeline.toTimelineValue(                (long) r.getUpperBound()            );            long lower;            long fixedAutoRange = (long) getFixedAutoRange();            if (fixedAutoRange > 0.0) {                lower = upper - fixedAutoRange;            }            else {                lower = this.timeline.toTimelineValue((long) r.getLowerBound());                double range = upper - lower;                long minRange = (long) getAutoRangeMinimumSize();                if (range < minRange) {                    long expand = (long) (minRange - range) / 2;                    upper = upper + expand;                    lower = lower - expand;                }                upper = upper + (long) (range * getUpperMargin());                lower = lower - (long) (range * getLowerMargin());            }            upper = this.timeline.toMillisecond(upper);            lower = this.timeline.toMillisecond(lower);            DateRange dr = new DateRange(new Date(lower), new Date(upper));            setRange(dr, false, false);        }    }    /**     * Selects an appropriate tick value for the axis.  The strategy is to     * display as many ticks as possible (selected from an array of 'standard'     * tick units) without the labels overlapping.     *     * @param g2  the graphics device.     * @param dataArea  the area defined by the axes.     * @param edge  the axis location.     */    protected void selectAutoTickUnit(Graphics2D g2,                                       Rectangle2D dataArea,                                      RectangleEdge edge) {        if (RectangleEdge.isTopOrBottom(edge)) {            selectHorizontalAutoTickUnit(g2, dataArea, edge);        }        else if (RectangleEdge.isLeftOrRight(edge)) {            selectVerticalAutoTickUnit(g2, dataArea, edge);        }    }    /**     * Selects an appropriate tick size for the axis.  The strategy is to     * display as many ticks as possible (selected from a collection of      * 'standard' tick units) without the labels overlapping.     *     * @param g2  the graphics device.     * @param dataArea  the area defined by the axes.     * @param edge  the axis location.     */    protected void selectHorizontalAutoTickUnit(Graphics2D g2,                                                 Rectangle2D dataArea,                                                 RectangleEdge edge) {        long shift = 0;        if (this.timeline instanceof SegmentedTimeline) {            shift = ((SegmentedTimeline) this.timeline).getStartTime();        }        double zero = valueToJava2D(shift + 0.0, dataArea, edge);        double tickLabelWidth             = estimateMaximumTickLabelWidth(g2, getTickUnit());        // start with the current tick unit...        TickUnitSource tickUnits = getStandardTickUnits();        TickUnit unit1 = tickUnits.getCeilingTickUnit(getTickUnit());        double x1 = valueToJava2D(shift + unit1.getSize(), dataArea, edge);        double unit1Width = Math.abs(x1 - zero);        // then extrapolate...        double guess = (tickLabelWidth / unit1Width) * unit1.getSize();        DateTickUnit unit2 = (DateTickUnit) tickUnits.getCeilingTickUnit(guess);        double x2 = valueToJava2D(shift + unit2.getSize(), dataArea, edge);        double unit2Width = Math.abs(x2 - zero);        tickLabelWidth = estimateMaximumTickLabelWidth(g2, unit2);        if (tickLabelWidth > unit2Width) {            unit2 = (DateTickUnit) tickUnits.getLargerTickUnit(unit2);        }        setTickUnit(unit2, false, false);    }        /**     * Selects an appropriate tick size for the axis.  The strategy is to     * display as many ticks as possible (selected from a collection of      * 'standard' tick units) without the labels overlapping.     *     * @param g2  the graphics device.     * @param dataArea  the area in which the plot should be drawn.     * @param edge  the axis location.     */    protected void selectVerticalAutoTickUnit(Graphics2D g2,                                              Rectangle2D dataArea,                                              RectangleEdge edge) {        // start with the current tick unit...        TickUnitSource tickUnits = getStandardTickUnits();        double zero = valueToJava2D(0.0, dataArea, edge);        // start with a unit that is at least 1/10th of the axis length        double estimate1 = getRange().getLength() / 10.0;        DateTickUnit candidate1             = (DateTickUnit) tickUnits.getCeilingTickUnit(estimate1);        double labelHeight1 = estimateMaximumTickLabelHeight(g2, candidate1);        double y1 = valueToJava2D(candidate1.getSize(), dataArea, edge);        double candidate1UnitHeight = Math.abs(y1 - zero);        // now extrapolate based on label height and unit height...        double estimate2             = (labelHeight1 / candidate1UnitHeight) * candidate1.getSize();        DateTickUnit candidate2             = (DateTickUnit) tickUnits.getCeilingTickUnit(estimate2);        double labelHeight2 = estimateMaximumTickLabelHeight(g2, candidate2);        double y2 = valueToJava2D(candidate2.getSize(), dataArea, edge);        double unit2Height = Math.abs(y2 - zero);       // make final selection...       DateTickUnit finalUnit;       if (labelHeight2 < unit2Height) {           finalUnit = candidate2;       }       else {           finalUnit = (DateTickUnit) tickUnits.getLargerTickUnit(candidate2);       }       setTickUnit(finalUnit, false, false);    }    /**     * Estimates the maximum width of the tick labels, assuming the specified      * tick unit is used.     * <P>     * Rather than computing the string bounds of every tick on the axis, we     * just look at two values: the lower bound and the upper bound for the      * axis.  These two values will usually be representative.     *     * @param g2  the graphics device.     * @param unit  the tick unit to use for calculation.     *     * @return The estimated maximum width of the tick labels.     */    private double estimateMaximumTickLabelWidth(Graphics2D g2,                                                  DateTickUnit unit) {        RectangleInsets tickLabelInsets = getTickLabelInsets();        double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();        Font tickLabelFont = getTickLabelFont();        FontRenderContext frc = g2.getFontRenderContext();        LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);        if (isVerticalTickLabels()) {            // all tick labels have the same width (equal to the height of             // the font)...            result += lm.getHeight();        }        else {            // look at lower and upper bounds...            DateRange range = (DateRange) getRange();            Date lower = range.getLowerDate();            Date upper = range.getUpperDate();            String lowerStr = null;            String upperStr = null;            DateFormat formatter = getDateFormatOverride();            if (formatter != null) {                lowerStr = formatter.format(lower);                upperStr = formatter.format(upper);            }            else {                lowerStr = unit.dateToString(lower);                upperStr = unit.dateToString(upper);            }            FontMetrics fm = g2.getFontMetrics(tickLabelFont);            double w1 = fm.stringWidth(lowerStr);            double w2 = fm.stringWidth(upperStr);            result += Math.max(w1, w2);        }        return result;    }    /**     * Estimates the maximum width of the tick labels, assuming the specified      * tick unit is used.     * <P>     * Rather than computing the string bounds of every tick on the axis, we      * just look at two values: the lower bound and the upper bound for the      * axis.  These two values will usually be representative.     *     * @param g2  the graphics device.     * @param unit  the tick unit to use for calculation.     *     * @return The estimated maximum width of the tick labels.     */    private double estimateMaximumTickLabelHeight(Graphics2D g2,                                                   DateTickUnit unit) {        RectangleInsets tickLabelInsets = getTickLabelInsets();        double result = tickLabelInsets.getTop() + tickLabelInsets.getBottom();        Font tickLabelFont = getTickLabelFont();        FontRenderContext frc = g2.getFontRenderContext();        LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);        if (!isVerticalTickLabels()) {            // all tick labels have the same width (equal to the height of             // the font)...            result += lm.getHeight();        }        else {            // look at lower and upper bounds...            DateRange range = (DateRange) getRange();            Date lower = range.getLowerDate();            Date upper = range.getUpperDate();            String lowerStr = null;            String upperStr = null;            DateFormat formatter = getDateFormatOverride();            if (formatter != null) {                lowerStr = formatter.format(lower);                upperStr = formatter.format(upper);            }            else {                lowerStr = unit.dateToString(lower);                upperStr = unit.dateToString(upper);            }            FontMetrics fm = g2.getFontMetrics(tickLabelFont);            double w1 = fm.stringWidth(lowerStr);            double w2 = fm.stringWidth(upperStr);            result += Math.max(w1, w2);        }        return result;    }    /**     * Calculates the positions of the tick labels for the axis, storing the      * results in the tick label list (ready for drawing).     *

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?