axislabellayout.java

来自「用applet实现很多应用小程序」· Java 代码 · 共 598 行 · 第 1/2 页

JAVA
598
字号

        for ( double x, v=vlo; v<=m_hi; v+=step ) {
            x = ((v-m_lo)/span)*breadth;
            if ( x < -0.5 ) {
                continue;
            } else if ( (r=index.get(v)) >= 0 ) {
                VisualItem item = labels.getItem(r);
                item.setVisible(true);
                item.setEndVisible(true);
            } else {
                VisualItem item = labels.addItem();
                item.set(LABEL, m_nf.format(v));
                item.setDouble(VALUE, v);
                double f = pspan==0 ? 0 : ((v-m_prevlo)/pspan);
                if ( f <= 0 || f >= 1.0 ) item.setStartVisible(true);
                set(item, f*breadth, b);
                set(item, x, b);
            }
        }
    }
    
    /**
     * Calculates a quantitative, square root scaled layout.
     */
    protected void sqrtLayout(VisualTable labels) {
        Rectangle2D b = getLayoutBounds();
        double breadth = getBreadth(b);
        
        double span = m_hi-m_lo;
        double splo = MathLib.safeSqrt(m_prevlo);
        double spspan = MathLib.safeSqrt(m_prevhi)-splo;
        double vlo = Math.pow(10, Math.floor(MathLib.safeLog10(m_lo)));
        double slo = MathLib.safeSqrt(m_lo);
        double sspan = MathLib.safeSqrt(m_hi)-slo;
        
        // mark previously visible labels
        Iterator iter = labels.tuples();
        while ( iter.hasNext() ) {
            VisualItem item = (VisualItem)iter.next();
            reset(item);
            double v = item.getDouble(VALUE);
            double x = span==0 ? 0 : ((MathLib.safeSqrt(v)-slo)/sspan)*breadth;
            set(item, x, b);
        }
        
        Index index = labels.index(VALUE);
        double step = getLinearStep(span, breadth/span);
        if ( step == 0 ) step = 1;
        int r;
        for ( double x, v=vlo; v<=m_hi; v+=step ) {
            x = ((MathLib.safeSqrt(v)-slo)/sspan)*breadth;
            if ( x < -0.5 ) {
                continue;
            } else if ( (r=index.get(v)) >= 0 ) {
                VisualItem item = labels.getItem(r);
                item.setVisible(true);
                item.setEndVisible(true);
            } else {
                VisualItem item = labels.addItem();
                item.set(LABEL, m_nf.format(v));
                item.setDouble(VALUE, v);
                double f = spspan==0 ? 0 : ((MathLib.safeSqrt(v)-splo)/spspan);
                if ( f <= 0 || f >= 1.0 ) {
                    item.setStartVisible(true);
                }
                set(item, f*breadth, b);
                set(item, x, b);
            }
        }
    }
    
    /**
     * Calculates a quantitative, logarithmically-scaled layout.
     * TODO: This method is currently not working correctly.
     */
    protected void logLayout(VisualTable labels) {
        Rectangle2D b = getLayoutBounds();
        double breadth = getBreadth(b);
        
        labels.clear();
        
        // get span in log space
        // get log of the difference
        // if [0.1,1) round to .1's 0.1-->0.1
        // if [1,10) round to 1's  1-->1
        // if [10,100) round to 10's 10-->10
        double llo = MathLib.safeLog10(m_lo);
        double lhi = MathLib.safeLog10(m_hi);
        double lspan = lhi - llo;
        
        double d = MathLib.log10(lhi-llo);
        int e = (int)Math.floor(d);
        int ilo = (int)Math.floor(llo);
        int ihi = (int)Math.ceil(lhi);
        
        double start = Math.pow(10,ilo);
        double end = Math.pow(10, ihi);
        double step = start * Math.pow(10, e);
        //System.out.println((hi-lo)+"\t"+e+"\t"+start+"\t"+end+"\t"+step);

        // TODO: catch infinity case if diff is zero
        // figure out label cases better
        for ( double val, v=start, i=0; v<=end; v+=step, ++i ) {
            val = MathLib.safeLog10(v);
            if ( i != 0 && Math.abs(val-Math.round(val)) < 0.0001 ) {
                i = 0;
                step = 10*step;
            }
            val = ((val-llo)/lspan)*breadth;
            if ( val < -0.5 ) continue;
            
            VisualItem item = labels.addItem();
            set(item, val, b);
            String label = i==0 ? m_nf.format(v) : null;
            item.set(LABEL, label);
            item.setDouble(VALUE, v);
        }
    }
    
    /**
     * Get the "breadth" of a rectangle, based on the axis type.
     */
    protected double getBreadth(Rectangle2D b) {
        switch ( m_axis ) {
        case Constants.X_AXIS:
            return b.getWidth();
        default:
            return b.getHeight();
        }
    }
    
    /**
     * Adjust a value according to the current scale type.
     */
    protected double adjust(double v) {
        switch ( m_scale ) {
        case Constants.LOG_SCALE:
            return Math.pow(10,v);
        case Constants.SQRT_SCALE:
            return v*v;
        case Constants.LINEAR_SCALE:
        default:
            return v;
        }
    }
    
    /**
     * Compute a linear step between axis marks.
     */
    protected double getLinearStep(double span, double scale) {
        double log10 = Math.log(span)/Math.log(10);
        double step = Math.pow(10, Math.floor(log10));
        
        double delta = step * scale / m_spacing;
        if (delta > 20) {
            step /= 20;
        } else if (delta > 10) {
            step /= 10;
        } else if (delta > 5) {
            step /= 5;
        } else if (delta > 4) {
            step /= 4;
        } else if (delta > 2) {
            step /= 2;
        } else if (delta < 1) {
            step *= 2;
        }
        return step;
    }
    
    // ------------------------------------------------------------------------
    // Ordinal Axis Layout
    
    /**
     * Compute an ordinal layout of axis marks.
     */
    protected void ordinalLayout(VisualTable labels) {
        ObjectRangeModel model = (ObjectRangeModel)m_model;
        double span = m_hi-m_lo;
        double pspan = m_prevhi-m_prevlo;
        
        Rectangle2D b = getLayoutBounds();
        double breadth = getBreadth(b);
        double scale = breadth/span;
        int step = getOrdinalStep(span, scale);
        if ( step <= 0 ) step = 1;
        
        // mark previously visible labels
        Iterator iter = labels.tuples();
        while ( iter.hasNext() ) {
            VisualItem item = (VisualItem)iter.next();
            reset(item);
            double v = item.getDouble(VALUE);
            double x = span==0 ? 0 : ((v-m_lo)/span)*breadth;
            set(item, x, b);
        }

        Index index = labels.index(VALUE);
        
        // handle remaining labels
        for ( int r, v=(int)m_lo; v<=m_hi; v+=step ) {
            if ( (r=index.get((double)v)) >= 0 ) {
                VisualItem item = labels.getItem(r);
                item.set(VisualItem.LABEL, model.getObject(v).toString());
                item.setVisible(true);
                item.setEndVisible(true);
            } else {
                VisualItem item = labels.addItem();
                item.set(VisualItem.LABEL, model.getObject(v).toString());
                item.setDouble(VisualItem.VALUE, v);
                double f = pspan==0 ? 0 : ((v-m_prevlo)/pspan);
                if ( f <= 0 || f >= 1.0 ) item.setStartVisible(true);
                set(item, f*breadth, b);
                set(item, (v-m_lo)*breadth/span, b);
            }
        }
    }
    
    /**
     * Compute an ordinal step between axis marks.
     */
    protected int getOrdinalStep(double span, double scale) {
        return (scale >= m_spacing ? 1 : (int)Math.ceil(m_spacing/scale));
    }
    
    // ------------------------------------------------------------------------
    // Auxiliary methods
    
    /**
     * Set the layout values for an axis label item.
     */
    protected void set(VisualItem item, double xOrY, Rectangle2D b) {
        switch ( m_axis ) {
        case Constants.X_AXIS:
            xOrY = m_asc ? xOrY + b.getMinX() : b.getMaxX() - xOrY;
            PrefuseLib.updateDouble(item, VisualItem.X,  xOrY);
            PrefuseLib.updateDouble(item, VisualItem.Y,  b.getMinY());
            PrefuseLib.updateDouble(item, VisualItem.X2, xOrY);
            PrefuseLib.updateDouble(item, VisualItem.Y2, b.getMaxY());
            break;
        case Constants.Y_AXIS:
            xOrY = m_asc ? b.getMaxY() - xOrY - 1 : xOrY + b.getMinY();
            PrefuseLib.updateDouble(item, VisualItem.X,  b.getMinX());
            PrefuseLib.updateDouble(item, VisualItem.Y,  xOrY);
            PrefuseLib.updateDouble(item, VisualItem.X2, b.getMaxX());
            PrefuseLib.updateDouble(item, VisualItem.Y2, xOrY);
        }
    }
    
    /**
     * Reset an axis label VisualItem
     */
    protected void reset(VisualItem item) {
        item.setVisible(false);
        item.setEndVisible(false);
        item.setStartStrokeColor(item.getStrokeColor());
        item.revertToDefault(VisualItem.STROKECOLOR);
        item.revertToDefault(VisualItem.ENDSTROKECOLOR);
        item.setStartTextColor(item.getTextColor());
        item.revertToDefault(VisualItem.TEXTCOLOR);
        item.revertToDefault(VisualItem.ENDTEXTCOLOR);
        item.setStartFillColor(item.getFillColor());
        item.revertToDefault(VisualItem.FILLCOLOR);
        item.revertToDefault(VisualItem.ENDFILLCOLOR);
    }
    
    /**
     * Remove axis labels no longer being used.
     */
    protected void garbageCollect(VisualTable labels) {
        Iterator iter = labels.tuples();
        while ( iter.hasNext() ) {
            VisualItem item = (VisualItem)iter.next();
            if ( !item.isStartVisible() && !item.isEndVisible() ) {
                labels.removeTuple(item);
            }
        }
    }
    
    /**
     * Create a new table for representing axis labels.
     */
    protected VisualTable getTable() {
        TupleSet ts = m_vis.getGroup(m_group);
        if ( ts == null ) {
            Schema s = PrefuseLib.getAxisLabelSchema();
            VisualTable vt = m_vis.addTable(m_group, s);
            vt.index(VALUE);
            return vt;
        } else if ( ts instanceof VisualTable ) {
            return (VisualTable)ts;
        } else {
            throw new IllegalStateException(
                "Group already exists, not being used for labels");
        }
    }
    
} // end of class AxisLabels

⌨️ 快捷键说明

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