Android 如何旋转图形上的文本值

Android 如何旋转图形上的文本值,android,androidplot,Android,Androidplot,我有一个使用androidplot构建的图表。我需要水平查看每个值(旋转90度)。在截图中我展示了我的意思。怎么做? 没有内置的配置选项来实现这一点,但在一个应用程序中,这相对容易实现。以下是修改后的方法: import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.DashPathEffect; import androi

我有一个使用androidplot构建的图表。我需要水平查看每个值(旋转90度)。在截图中我展示了我的意思。怎么做?

没有内置的配置选项来实现这一点,但在一个应用程序中,这相对容易实现。以下是修改后的方法:

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Bundle;
import android.support.annotation.NonNull;

import com.androidplot.ui.SeriesRenderer;
import com.androidplot.util.PixelUtils;
import com.androidplot.xy.CatmullRomInterpolator;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.LineAndPointRenderer;
import com.androidplot.xy.PointLabelFormatter;
import com.androidplot.xy.PointLabeler;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYGraphWidget;
import com.androidplot.xy.XYPlot;
import com.androidplot.xy.XYSeries;

import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.util.Arrays;
import java.util.List;

/**
 * A simple XYPlot
 */
public class SimpleXYPlotActivity extends Activity {

    private XYPlot plot;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.simple_xy_plot_example);

        // initialize our XYPlot reference:
        plot = (XYPlot) findViewById(R.id.plot);

        // create a couple arrays of y-values to plot:
        final Number[] domainLabels = {1, 2, 3, 6, 7, 8, 9, 10, 13, 14};
        Number[] series1Numbers = {1, 4, 2, 8, 4, 16, 8, 32, 16, 64};
        Number[] series2Numbers = {5, 2, 10, 5, 20, 10, 40, 20, 80, 40};

        // turn the above arrays into XYSeries':
        // (Y_VALS_ONLY means use the element index as the x value)
        XYSeries series1 = new SimpleXYSeries(
                Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series1");
        XYSeries series2 = new SimpleXYSeries(
                Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");

        // create formatters to use for drawing a series using LineAndPointRenderer
        // and configure them from xml:
        LineAndPointFormatter series1Format =
                new MyLineAndPointFormatter(this, R.xml.line_point_formatter_with_labels);

        LineAndPointFormatter series2Format =
                new MyLineAndPointFormatter(this, R.xml.line_point_formatter_with_labels_2);

        // add an "dash" effect to the series2 line:
        series2Format.getLinePaint().setPathEffect(new DashPathEffect(new float[] {

                // always use DP when specifying pixel sizes, to keep things consistent across devices:
                PixelUtils.dpToPix(20),
                PixelUtils.dpToPix(15)}, 0));

        // (optional) add some smoothing to the lines:
        // see: http://androidplot.com/smooth-curves-and-androidplot/
        series1Format.setInterpolationParams(
                new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));

        series2Format.setInterpolationParams(
                new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));

        // add a new series' to the xyplot:
        plot.addSeries(series1, series1Format);
        plot.addSeries(series2, series2Format);

        plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
            @Override
            public StringBuffer format(Object obj, @NonNull StringBuffer toAppendTo, @NonNull FieldPosition pos) {
                int i = Math.round(((Number) obj).floatValue());
                return toAppendTo.append(domainLabels[i]);
            }
            @Override
            public Object parseObject(String source, @NonNull ParsePosition pos) {
                return null;
            }
        });
    }

    /**
     * A LineAndPointRenderer that rotates it's point labels -90 degrees.
     */
    static class MyLineAndPointRenderer extends LineAndPointRenderer<MyLineAndPointFormatter> {

        public MyLineAndPointRenderer(XYPlot plot) {
            super(plot);
        }

        // Basically just copy the entire renderPoints implementation and add a rotation as shown below
        @Override
        protected void renderPoints(Canvas canvas, RectF plotArea, XYSeries series, int iStart, int iEnd, List<PointF> points,
                                    LineAndPointFormatter formatter) {
            if (formatter.hasVertexPaint() || formatter.hasPointLabelFormatter()) {
                final Paint vertexPaint = formatter.hasVertexPaint() ? formatter.getVertexPaint() : null;
                final boolean hasPointLabelFormatter = formatter.hasPointLabelFormatter();
                final PointLabelFormatter plf = hasPointLabelFormatter ? formatter.getPointLabelFormatter() : null;
                final PointLabeler pointLabeler = hasPointLabelFormatter ? formatter.getPointLabeler() : null;
                for(int i = iStart; i < iEnd; i++) {
                    PointF p = points.get(i);
                    if(p != null) {

                        if (vertexPaint != null) {
                            canvas.drawPoint(p.x, p.y, vertexPaint);
                        }

                        if (pointLabeler != null) {
                            // this is where we rotate the text:
                            final int canvasState = canvas.save();
                            try {
                                canvas.rotate(-90, p.x, p.y);
                                canvas.drawText(pointLabeler.getLabel(series, i),
                                        p.x + plf.hOffset, p.y + plf.vOffset, plf.getTextPaint());
                            } finally {
                                canvas.restoreToCount(canvasState);
                            }
                        }
                    }
                }
            }
        }

    }

    static class MyLineAndPointFormatter extends LineAndPointFormatter {

        // if you dont use configurator you can omit this constructor.  this example uses it
        // tho so here it is.
        public MyLineAndPointFormatter(Context context, int xmlCfgId) {
            super(context, xmlCfgId);
        }

        @Override
        public Class<? extends SeriesRenderer> getRendererClass() {
            return MyLineAndPointRenderer.class;
        }

        @Override
        public SeriesRenderer doGetRendererInstance(XYPlot plot) {
            return new MyLineAndPointRenderer(plot);
        }

    }
}
导入android.app.Activity;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.DashPathEffect;
导入android.graphics.Paint;
导入android.graphics.PointF;
导入android.graphics.RectF;
导入android.os.Bundle;
导入android.support.annotation.NonNull;
导入com.androidplot.ui.SeriesRenderer;
导入com.androidplot.util.PixelUtils;
导入com.androidplot.xy.CatmullRomInterpolator;
导入com.androidplot.xy.LineAndPointFormatter;
导入com.androidplot.xy.LineAndPointRenderer;
导入com.androidplot.xy.PointLabelFormatter;
导入com.androidplot.xy.PointLabeler;
导入com.androidplot.xy.SimpleXYSeries;
导入com.androidplot.xy.XYGraphWidget;
导入com.androidplot.xy.XYPlot;
导入com.androidplot.xy.XYSeries;
导入java.text.FieldPosition;
导入java.text.Format;
导入java.text.ParsePosition;
导入java.util.array;
导入java.util.List;
/**
*简单的XYPlot
*/
公共类SimpleXYPlotActivity扩展了活动{
私有地块;
@凌驾
创建时的公共void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_xy_plot_示例);
//初始化XYPlot引用:
plot=(XYPlot)findviewbyd(R.id.plot);
//创建要打印的两个y值数组:
最终数字[]域标签={1,2,3,6,7,8,9,10,13,14};
编号[]系列1编号={1,4,2,8,4,16,8,32,16,64};
编号[]系列2编号={5,2,10,5,20,10,40,20,80,40};
//将上述阵列转换为XYSeries':
//(Y_VALS_仅表示使用元素索引作为x值)
XYSeries系列1=新的SimpleXYSeries系列(
Arrays.asList(series1number),SimpleXYSeries.ArrayFormat.Y_VALS_仅限“Series1”);
XYSeries系列2=新的SimpleXYSeries系列(
Arrays.asList(Series2编号),SimpleXYSeries.ArrayFormat.Y_VALS_仅限“Series2”);
//创建用于使用LineAndPointRenderer绘制系列的格式化程序
//并从xml中配置它们:
LineAndPointFormatter系列1格式=
新的MyLineAndPointFormatter(这个,R.xml.line\u point\u格式化程序\u带有\u标签);
LineAndPointFormatter系列2格式=
新的MyLineAndPointFormatter(这个,R.xml.line\u point\u格式化程序\u,带有标签\u 2);
//将“破折号”效果添加到序列2行:
series2Format.getLinePaint().setPathEffect(新DashPathEffect(新浮点[]{
//在指定像素大小时始终使用DP,以保持设备之间的一致性:
PixelUtils.dpToPix(20),
dpToPix(15)},0);
//(可选)向线添加一些平滑:
//见:http://androidplot.com/smooth-curves-and-androidplot/
series1Format.setInterpolationParams(
新的CatmullRomInterpolator.Params(10,CatmullRomInterpolator.Type.向心);
series2Format.setInterpolationParams(
新的CatmullRomInterpolator.Params(10,CatmullRomInterpolator.Type.向心);
//向xyplot添加新系列:
绘图。添加系列(系列1、系列1格式);
绘图。添加系列(系列2、系列2格式);
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(新格式(){
@凌驾
公共StringBuffer格式(对象对象obj、@NonNull StringBuffer toAppendTo、@NonNull FieldPosition pos){
inti=Math.round(((Number)obj.floatValue());
返回到appendto.append(domainLabels[i]);
}
@凌驾
公共对象parseObject(字符串源,@NonNull ParsePosition pos){
返回null;
}
});
}
/**
*将其点标签旋转90度的LineAndPointRenderer。
*/
静态类MyLineAndPointRenderer扩展了LineAndPointRenderer{
公共MyLineAndPointRenderer(XYPlot){
超级(情节);
}
//基本上只需复制整个renderPoints实现并添加旋转,如下所示
@凌驾
受保护的无效渲染点(画布、RectF绘图区、XYSeries系列、int iStart、int iEnd、列表点、,
LineAndPointFormatter(格式化程序){
if(formatter.hasVertexPaint()| | formatter.hasPointLabelFormatter()){
final Paint vertexPaint=格式化程序.hasVertexPaint()?格式化程序.getVertexPaint():null;
最终布尔值hasPointLabelFormatter=格式化程序。hasPointLabelFormatter();
final PointLabelFormatter plf=hasPointLabelFormatter?格式化程序。getPointLabelFormatter():null;
final PointLabeler PointLabeler=hasPointLabelFormatter?格式化程序。getPointLabeler():null;
for(int i=iStart;i