IT技术生产力

MPAndroidChart文档

2018-12-04  本文已影响473人  你吼那么大声干什么

开始

添加依赖

在第一步,需要将依赖的库添加到你的项目中

创建View

想要使用 LineChart,BarChart,ScatterChart,CandleStickChart,PieChart,BubbleChart或者RadarChart,需要先在xml中定义

<com.github.mikephil.charting.charts.LineChart
     android:id="@+id/chart"
     android:layout_width="match_parent"
     android:layout_height="match_parent" />

然后在你的Activity或者Fragment中获取控件

LineChart chart = (LineChart) findViewById(R.id.chart);

或者使用代码创建,在布局中添加

LineChart chart = new LineChart(Context);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.relativeLayout);
rl.add(chart);

添加数据

在你拥有了图表的实例之后,你可以创建数据并添加到图表中.下面是一个使用折线图的例子,每一条数据都可以使用Entry这个类来标识x,y坐标.
在其他图表类型中,比如BarChart使用其他的类(比如BarEntry)来达到相同的目的.

添加数据到图表中,需要将所有的数据都包裹在Entry对象中

YourData[] dataObjects = ...;

List<Entry> entries = new ArrayList<Entry>();

for (YourData data : dataObjects) {
    entries.add(new Entry(data.getValueX(), data.getValueY())); 
}

然后,你需要给你创建的LineDataSet对象添加List<Entry>数据集合,DataSet对象持有数据,这些数据用户可以自定义样式.
下面的"Label"用于描述数据的作用,如果图例开启的话,还会作为图例显示在图表上

LineDataSet dataSet = new LineDataSet(entries, "Label"); // 添加数据
dataSet.setColor(...);
dataSet.setValueTextColor(...); // 自定义数据样式

最后一步,你需要把创建好的LineDataSet添加到LineData中,添加完数据,利用Chart的实例去设置数据,并且刷新一下

LineData lineData = new LineData(dataSet);
chart.setData(lineData);
chart.invalidate(); // 刷新



图表的交互

这个库可以让你最大限度的通过手势触摸与图表交互,并且通过回调函数获取反馈

开启/关闭交互

图表滑动

手势操作回调

如果使用手势操作图表,可以使用OnChartGestureListener来监听回调

public interface OnChartGestureListener {

    //当手指刚触摸到图表时触发,action_down
    void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture);

    //当手指在图表上操作结束时调用,action_up、action_cancel
    void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture);

    //长按图表回调
    public void onChartLongPressed(MotionEvent me);

    //双击图表回调
    public void onChartDoubleTapped(MotionEvent me);

    //单击图表回调
    public void onChartSingleTapped(MotionEvent me);

    //滑动图表回调
    public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY);

    //缩放图表回调
    public void onChartScale(MotionEvent me, float scaleX, float scaleY);

    //拖拽图表回调
    public void onChartTranslate(MotionEvent me, float dX, float dY);
}

将你的Chart去设置手势监听器就可以实现这些回调

chart.setOnChartGestureListener(this);



高亮显示

开启/关闭高亮

高亮样式可以由个人自定义

dataSet.setHighlightEnabled(true); // 是否允许高亮
dataSet.setDrawHighlightIndicators(true); // 设置是否有拖拽高亮指示器
dataSet.setHighlightColor(Color.BLACK); // 设置高亮颜色

代码高亮数据

选择回调

OnChartValueSelectedListener,通过触摸高亮数据时的回调

public interface OnChartValueSelectedListener {
    
    //当图表内的一项被选中时的回调
    public void onValueSelected(Entry e, Highlight h);
    
    //当没有选择项时的回调
    public void onNothingSelected();
}

Highlight类

Highlight类,通常被用于获取高亮条目的信息,或者用来给图表或者Entry对提供数据用于高亮,Highlight类提供两个构造函数

 //标准的Highlight构造函数
 public Highlight(float x, int dataSetIndex) { ... }

 //给BarEntry使用的Highlight构造函数
 public Highlight(float x, int dataSetIndex, int stackIndex) { ... }

一个通过代码方式利用Highlight进行高亮的例子

// highlight the entry and x-position 50 in the first (0) DataSet
Highlight highlight = new Highlight(50f, 0); 

chart.highlightValue(highlight, false); // highlight this value, don't call listener

自定义高亮

所有用户输入的手势高亮形式都是由默认的ChartHighlighter类完成的,通过自定义ChartHighlighter类的实现来替换默认的,完成更多的不同的高亮形式
setHighlighter(ChartHighlighter highlighter): 传入自定义的ChartHighlighter实现类对象来完成高亮样式的设置




坐标轴

坐标轴类通过以下部分实现具体的样式

控制坐标轴的哪些部分可以被绘制

定制坐标轴的范围(最小/最大)

定制坐标轴样式

对坐标轴值进行格式化

可以使用IAxisValueFormatter接口来格式化坐标轴数据,使用axis.setValueFormatter(IAxisValueFormatter formatter)设置自己的定制数据格式

限制线

像边界线和约束线这种用于表示特殊信息的线我们称之为限制线,限制线在Y轴上横向呈现,在X轴上纵向呈现

限制线顾名思义是给用户提供格外信息的一种简洁、简单的线

例如,您的图表可能会显示用户的各种血压测量结果.为了通知用户,收缩压超过140毫米汞柱被认为是健康风险,你可以在140添加一个限制线来提供这些信息

YAxis leftAxis = chart.getAxisLeft();

LimitLine ll = new LimitLine(140f, "健康的血压线");
ll.setLineColor(Color.RED);
ll.setLineWidth(4f);
ll.setTextColor(Color.BLACK);
ll.setTextSize(12f);
// .. 更多的样式设置

leftAxis.addLimitLine(ll);



X轴

任何与横轴有关的数据信息都存放在X轴中,像折线图、柱状图、网状图、蜡烛图、雷达图等都有XAxis对象

获取X轴实例对象使用

XAxis xAxis = chart.getXAxis();

定制坐标轴数据

示例代码

XAxis xAxis = chart.getXAxis();
xAxis.setPosition(XAxisPosition.BOTTOM);
xAxis.setTextSize(10f);
xAxis.setTextColor(Color.RED);
xAxis.setDrawAxisLine(true);
xAxis.setDrawGridLines(false);
// 设置定制的数据格式
xAxis.setValueFormatter(new MyCustomFormatter()); 



Y轴

任何与纵轴有关的数据信息都存放在Y轴中,像折线图、柱状图、网状图、蜡烛图等都有左右两个YAxis对象,雷达图只有一个YAxis对象

获取YAxis实例对象

YAxis leftAxis = chart.getAxisLeft();
YAxis rightAxis = chart.getAxisRight();

YAxis leftAxis = chart.getAxis(AxisDependency.LEFT);

YAxis yAxis = radarChart.getYAxis(); // 雷达图获取YAxis方法

在运行时,可以使用public AxisDependency getAxisDependency()来确定YAxis是图表的哪一边的
想要设置效果必须在给图表设置数据之前

Axis Dependency

默认情况下,所有添加到图表的数据都和左边的Y轴数据相对应,没有进一步设置的情况下右边的Y轴数据以及样式比例均与左边统一,如果你想要设置不同比例的Y轴,你可以通过设置对应的数据来绘制对应的坐标轴实现

LineDataSet dataSet = ...; // 获取dataset
dataSet.setAxisDependency(AxisDependency.RIGHT);

零线

除了网格线与YAxis上的每个值水平并排,还有所谓的零线,它在轴上的零(0)值处绘制,类似于网格线,但可以单独配置。

零线代码示例:

// 数据设置在左边坐标轴
YAxis left = mChart.getAxisLeft();
left.setDrawLabels(false); // 不设置坐标轴数据标签
left.setDrawAxisLine(false); // 不绘制坐标轴线
left.setDrawGridLines(false); // 不绘制网格线
left.setDrawZeroLine(true); // 绘制零线
mChart.getAxisRight().setEnabled(false); // 不设置右边Y轴
0line

没有其他的线(坐标轴线、网格线等等)只有一条零线的效果

更多的代码示例:

YAxis yAxis = mChart.getAxisLeft();
yAxis.setTypeface(...); // 设置一个不同的字体
yAxis.setTextSize(12f); // 设置字体大小
yAxis.setAxisMinimum(0f); // 设置坐标轴从0开始
yAxis.setAxisMaximum(100f); // 设置坐标轴最大值为100
yAxis.setTextColor(Color.BLACK); // 设置字体颜色为黑色
yAxis.setValueFormatter(new MyValueFormatter());
yAxis.setGranularity(1f); // 设置间隔为1
yAxis.setLabelCount(6, true); // 设置标签个数
//... 更多



设置数据

折线图

如果想要给图表添加数据需要使用以下方式:

public void setData(ChartData data) { ... }

基类CharData包含在渲染时图表所需要的所有的数据和信息
对于每一种数据图表,都有一个CharData的子类用于给图表设置数据

在构造函数中,可以使用List<? extends IDataSet>作为数据去显示,

两种不同的构造函数

    /** List constructor */
    public LineData(List<ILineDataSet> sets) { ... }

    /** Constructor with one or multiple ILineDataSet objects */
    public LineData(ILineDataSet...) { ... }

一个DataSet对象代表一组图表中一起的数据,这样可以在逻辑上分离图表上的不同组数据.
对于每种类型的图表,存在允许特定样式的扩展DataSet的不同对象(例如Line DataSet)

举个例子,如果你想要显示两家不同公司上一年季度性的财政收入,推荐使用两个LineDataSet,每一个中包含四组数据
那么如何去设置LineDataSet对象呢

public LineDataSet(List<Entry> entries,String label){...}

可以看到,LineDataSet的构造函数中需要List<Entry>一系列的数据以及用于描述数据信息的label,
此label还可以进一步在LineData中去找到对应的LineDataSet对象
这些Entry的列表中包含了图表的所有数据,而Entry类就相当于X、Y坐标值的一个包装类,用于存放一个具体的坐标值

public Entry(float x, float y) { ... }

上面的例子,我们第一步可以创建一个用于存放公司收入的Entry的集合

List<Entry> valsComp1 = new ArrayList<Entry>();
List<Entry> valsComp2 = new ArrayList<Entry>();

然后填充数据,确保Entry内的X轴数据是精确的

    Entry c1e1 = new Entry(0f, 100000f); // 一公司第一季度数据
    valsComp1.add(c1e1);
    Entry c1e2 = new Entry(1f, 140000f); // 一公司第二季度数据
    valsComp1.add(c1e2);
    // 继续添加
    
    Entry c2e1 = new Entry(0f, 130000f); // 二公司第一季度数据
    valsComp2.add(c2e1);
    Entry c2e2 = new Entry(1f, 115000f); // 二公司第二季度数据
    valsComp2.add(c2e2);
    //...

现在我们可以通过这一系列数据去创建LineDataSet对象

    LineDataSet setComp1 = new LineDataSet(valsComp1, "Company 1");
    setComp1.setAxisDependency(AxisDependency.LEFT);
    LineDataSet setComp2 = new LineDataSet(valsComp2, "Company 2");
    setComp2.setAxisDependency(AxisDependency.LEFT);

通过使用setAxisDependency来指定具体数据绘制的轴,然后通过创建IDataSets的List来构成ChartData对象

    // 使用ILineDataSet接口
    List<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
    dataSets.add(setComp1);
    dataSets.add(setComp2);
    
    LineData data = new LineData(dataSets);
    mLineChart.setData(data);
    mLineChart.invalidate(); // 刷新

在调用invalidate方法刷新后,数据就会被绘制出来

如果我们想特别定制X轴数据来替换原先的0到3,我们可以使用IAxisValueFormatter接口
这个接口可以让我们自定义X轴数据显示样式
举个例子,像以下这样设置数据格式:

// 绘制在X轴上的数据数组
final String[] quarters = new String[] { "Q1", "Q2", "Q3", "Q4" };

IAxisValueFormatter formatter = new IAxisValueFormatter() {

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        return quarters[(int) value];
    }

    @Override
    public int getDecimalDigits() {  return 0; }
};

XAxis xAxis = mLineChart.getXAxis();
xAxis.setGranularity(1f); // 最小的间隔设置为1
xAxis.setValueFormatter(formatter);

最后渲染的图表的样子


Formatter

BarChart,ScatterChart,BubbleChart和CandleStickChart的设置数据与LineChart一样
其中特殊的是BarChart将会在下面进行解释:

数据排序

如果List<Entry>没有正确的X轴排列顺序,可能导致一些意外的情况
我们可以使用EntryXComparator来进行排序

List<Entry> entries = ...;
Collections.sort(entries, new EntryXComparator());

柱状图

柱状图的设置数据方式与折线图类似,最大的不同在于柱状图存放数据的BarEntry有一些不同的样式设置

创建BarDataSet

List<BarEntry> entries = new ArrayList<>();
entries.add(new BarEntry(0f, 30f));
entries.add(new BarEntry(1f, 80f));
entries.add(new BarEntry(2f, 60f));
entries.add(new BarEntry(3f, 50f)); 
                                    // 跳过第五个
entries.add(new BarEntry(5f, 70f));
entries.add(new BarEntry(6f, 60f));

BarDataSet set = new BarDataSet(entries, "BarDataSet");

将数据设置到图表上

BarData data = new BarData(set);
data.setBarWidth(0.9f); // 设置数据条的宽度
chart.setData(data);
chart.setFitBars(true); // 让X轴与所有的数据条适配
chart.invalidate(); // 刷新

当柱状图被创建时,每一个条都有1f的宽度,设置为0.9f的宽度后,将会在两个条各存在0.1f的间隔
设置setFitBars(true)将会让X轴的范围很好的适配柱状图,而不会出现有哪个条被边缘线切断

刷新后显示:


barChart

群组柱状图

YourData[] group1 = ...;
YourData[] group2 = ...;

List<BarEntry> entriesGroup1 = new ArrayList<>();
List<BarEntry> entriesGroup2 = new ArrayList<>();

// 填充数据
for(int i = 0; i < group1.length; i++) {
    entriesGroup1.add(new BarEntry(i, group1.getValue()));
    entriesGroup2.add(new BarEntry(i, group2.getValue()));
}

//两组数据
BarDataSet set1 = new BarDataSet(entriesGroup1, "Group 1");
BarDataSet set2 = new BarDataSet(entriesGroup2, "Group 2");

这样就获取到两组数据,现在用这两组数据去完成群组柱状图

float groupSpace = 0.06f; //群组间的间隔
float barSpace = 0.02f; // 每一个柱状条间隔
float barWidth = 0.45f; // 每一个柱状条的宽度
// (0.02 + 0.45) * 2 + 0.06 = 1.00 -> 总共合起来还是1f

BarData data = new BarData(set1, set2); //设置组数据
data.setBarWidth(barWidth); // 设置柱状条宽度
barChart.setData(data);
barChart.groupBars(1980f, groupSpace, barSpace); // 设置组样式宽度等
barChart.invalidate(); // 刷新

groupBars(...)对群组数据进行了具体的设置,这个方法的具体参数

public void groupBars(float fromX, float groupSpace, float barSpace) { ... }

fromX标识X轴数据从哪边开始进行渲染

最后渲染出来为:


group_bar_chart

通过使用setCenterAxisLabels(...)方法可以让标签数据正确显示在群组柱状条中间

XAxis xAxis = chart.getXAxis();
xAxis.setCenterAxisLabels(true);

叠加柱状图

设置与普通的柱状图类似,不同的是BarEntry的构造函数使用

public BarEntry(float x, float [] yValues) { ... }

第二个参数是一个叠加的数据值数组

BarEntry stackedEntry = new BarEntry(0f, new float[] { 10, 20, 30 });

这样在图表上显示高度为10,20,30的三段数据

饼图

不同于其他的图形,饼图的构造函数是这样的:

public PieEntry(float value, String label) { ... }

第一个参数即是当前所占区域的大小数据,第二个参数用于描述当前区域的信息

完整的饼图的创建

List<PieEntry> entries = new ArrayList<>();

entries.add(new PieEntry(18.5f, "Green"));
entries.add(new PieEntry(26.7f, "Yellow"));
entries.add(new PieEntry(24.0f, "Red"));
entries.add(new PieEntry(30.8f, "Blue"));

PieDataSet set = new PieDataSet(entries, "Election Results");
PieData data = new PieData(set);
pieChart.setData(data);
pieChart.invalidate(); // 刷新

饼图没有X轴,数据的显示顺序由添加顺序来定义
渲染完成后:


pie_chart


设置颜色

在这个小例子中我们有两组数据用于代表两个公司季度收入,我们想要设置不同的颜色去区分它们
我们想要:

  LineDataSet setComp1 = new LineDataSet(valsComp1, "Company 1");
  setComp1.setColors(new int[] { R.color.red1, R.color.red2, R.color.red3, R.color.red4 }, Context);
  
  LineDataSet setComp2 = new LineDataSet(valsComp2, "Company 2");
  setComp2.setColors(new int[] { R.color.green1, R.color.green2, R.color.green3, R.color.green4 }, Context);

给DataSet设置颜色的方法

当然也可以使用颜色模板

LineDataSet set = new LineDataSet(...);
set.setColors(ColorTemplate.VORDIPLOM_COLORS);

在没有设置颜色的时候,将会使用默认的颜色




ValueFormatter接口

IValueFormatter接口用于创建自定义格式类来在图表绘制之前格式数据
使用IValueFormatter,简单的创建一个类去实现这个接口,并返回你从getFormattedValue(...)方法获取的数据想要显示的样子

创建一个格式化类

public class MyValueFormatter implements IValueFormatter {

    private DecimalFormat mFormat;
    
    public MyValueFormatter() {
        mFormat = new DecimalFormat("###,###,##0.0"); // 使用金融类型的格式
    }
    
    @Override
    public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
        // 写下你的代码逻辑
        return mFormat.format(value) + " $"; // 比如在数据前添加一个$符
    }
}

给ChartData或者DataSet添加格式化

// 图表内的数据均使用这种格式
lineData.setValueFormatter(new MyValueFormatter());

// 仅在该DataSet内使用这种格式
lineDataSet.setValueFormatter(new MyValueFormatter());

预置格式类




AxisValueFormatter接口

创建一个格式化类

创建一个类实现IAxisValueFormatter接口,用于格式化坐标轴上的值

public class MyYAxisValueFormatter implements IAxisValueFormatter {

    private DecimalFormat mFormat;

    public MyAxisValueFormatter() {
        //格式化数字
        mFormat = new DecimalFormat("###,###,##0.0");
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        // value参数标识在坐标轴上的位置或者说是数据值,axis标识是哪个坐标轴
        return mFormat.format(value) + " $";
    }
    
    /** 只有为数字时返回 其余返回0*/
    @Override
    public int getDecimalDigits() { return 1; }
}

下面的例子展示怎么把数组中的数据展示到坐标轴上去

public class MyXAxisValueFormatter implements IAxisValueFormatter {

    private String[] mValues;

    public MyXAxisValueFormatter(String[] values) {
        this.mValues = values;
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        return mValues[(int) value];
    }
    
    @Override
    public int getDecimalDigits() { return 0; }
}

设置格式化类

在创建好格式化类之后,简单去运用它

YAxis left = chart.getAxisLeft();
left.setValueFormatter(new MyYAxisValueFormatter());
String[] values = new String[] { ... };
XAxis xAxis = chart.getXAxis();
xAxis.setValueFormatter(new MyXAxisValueFormatter(values));

设置完之后,图表用格式化类来具体指定值来代替默认的坐标轴的最小值和最大值范围

限制间隔

如果使用上面的数组格式化坐标轴标签值,可以使用一下的代码去限制标签间的间隔

axis.setGranularity(1f);

这将可以预防坐标轴绘制重叠的数据,因为在缩放到一定的程度时,图表将会停止计算更小的标签范围

预置格式化类




通用的图表和样式设置

刷新

日志

大体的样式设置

下面是一些可以直接在Chart上使用的样式设置方法




具体的图表和样式设置

Line-, Bar-, Scatter-, Candle- & BubbleChart

BarChart

PieChart

RadarChart




图例

图例通常有一个标识和一字符串组成,标识为代表该数据的DataSet的颜色决定,字符串是DataSet的描述

获取图例对象

Legend legend = chart.getLegend();

设置图例的样式

大小

自定义图例

设置自定义的标签

例子

    Legend l = chart.getLegend();
    l.setFormSize(10f); 
    l.setForm(LegendForm.CIRCLE); 
    l.setPosition(LegendPosition.BELOW_CHART_LEFT);
    l.setTypeface(...);
    l.setTextSize(12f);
    l.setTextColor(Color.BLACK);
    l.setXEntrySpace(5f); 
    l.setYEntrySpace(5f); 

    l.setCustom(ColorTemplate.VORDIPLOM_COLORS, new String[] { "Set1", "Set2", "Set3", "Set4", "Set5" });

    // and many more...



动态实时数据

MPAndroidChart并不支持实时数据,但是为了向图表添加新数据或动态删除数据,有各种方法可以将Entry对象添加到已有的DataSet对象或从已有的ChartData对象中删除DataSet对象

动态添加删除数据

Class DataSet(以及所有子类):

Class ChartData(以及所有子类):

同样也有删除数据的方法

Class DataSet(以及所有子类):

Class ChartData(以及所有子类):

一定要记住

在动态删除或者添加数据之后,一定要在调用invalidate()刷新页面之前调用notifyDataSetChanged()方法更新数据

 // EXAMPLE 1
 // add entries to the "data" object
 exampleData.addEntry(...);
 chart.notifyDataSetChanged(); // 让Chart知道数据发生变化
 chart.invalidate(); // 刷新

 // EXAMPLE 2
 // add entries to "dataSet" object
 dataSet.addEntry(...);
 exampleData.notifyDataChanged(); // 让DataSet知道数据发生变化
 chart.notifyDataSetChanged(); // 让Chart知道数据发生变化
 chart.invalidate(); // 刷新



调整视窗显示

这些方法只适用于LineChart,BarChart,ScatterChart和CandleStickChart

规定哪些可以显示

移动View

使用动画移动View

所有的moveViewTo类似的方法都会自动调用invalidate方法去刷新页面,不需要手动去调用

缩放(以代码方式)

缩放动画

例子:

chart.setData(...);

// 开始设置视窗
chart.setVisibleXRangeMaximum(20); 
chart.moveViewToX(10);



动画

所有的图表都提供了动画以供操作使用

有三种不同的动画存在

mChart.animateX(3000); // animate horizontal 3000 milliseconds

mChart.animateY(3000); // animate vertical 3000 milliseconds

mChart.animateXY(3000, 3000); // animate horizontal and vertical 3000 milliseconds

平缓动画效果

你可以从Easing.EasingOption中选择想要的预置平缓动画效果

public enum EasingOption {
      Linear,
      EaseInQuad,
      EaseOutQuad,
      EaseInOutQuad,
      EaseInCubic,
      EaseOutCubic,
      EaseInOutCubic,
      EaseInQuart,
      EaseOutQuart,
      EaseInOutQuart,
      EaseInSine,
      EaseOutSine,
      EaseInOutSine,
      EaseInExpo,
      EaseOutExpo,
      EaseInOutExpo,
      EaseInCirc,
      EaseOutCirc,
      EaseInOutCirc,
      EaseInElastic,
      EaseOutElastic,
      EaseInOutElastic,
      EaseInBack,
      EaseOutBack,
      EaseInOutBack,
      EaseInBounce,
      EaseOutBounce,
      EaseInOutBounce,
}

有两种设置平缓动画效果的方法

public void animateY(int durationmillis, Easing.EasingOption option);

例如调用时就将动画效果设置进去

mChart.animateY(3000, Easing.EasingOption.EaseOutBack); 
public void animateY(int durationmillis, EasingFunction function); 

创建一个类去实现EasingFunction接口,在该类中实现自己的逻辑

/**
 * Interface for creating custom made easing functions. 
 */
 public interface EasingFunction {
    /**
     * Called everytime the animation is updated.
     * @param input - the time passed since the animation started (value between 0 and 1)
     */
     public float getInterpolation(float input);
 }

调用的时候(在Android3.0以下的版本中将会Crash掉)

mChart.animateY(3000, new MyEasingFunction()); 



IMarker接口(图表数据标注接口)

IMarker接口是你能够在创建自定义的标注样式去显示你图表中高亮的数据
IMarker定义的像这样:

public interface IMarker {

    /**
     * @return The desired (general) offset you wish the IMarker to have on the x- and y-axis.
     *         By returning x: -(width / 2) you will center the IMarker horizontally.
     *         By returning y: -(height / 2) you will center the IMarker vertically.
     */
    MPPointF getOffset();

    /**
     * @return The offset for drawing at the specific `point`. This allows conditional adjusting of the Marker position.
     *         If you have no adjustments to make, return getOffset().
     *
     * @param posX This is the X position at which the marker wants to be drawn.
     *             You can adjust the offset conditionally based on this argument.
     * @param posY This is the X position at which the marker wants to be drawn.
     *             You can adjust the offset conditionally based on this argument.
     */
    MPPointF getOffsetForDrawingAtPos(float posX, float posY);

    /**
     * 刷新方法
     *
     * @param e         The Entry the IMarker belongs to. This can also be any subclass of Entry, like BarEntry or
     *                  CandleEntry, simply cast it at runtime.
     * @param highlight The highlight object contains information about the highlighted value such as it's dataset-index, the
     *                  selected range or stack-index (only stacked bar entries).
     */
    void refreshContent(Entry e, Highlight highlight);

    /**
     * 使用传递来的Canvas对象在指定位置绘制对应的标注
     *
     * @param canvas
     * @param posX
     * @param posY
     */
    void draw(Canvas canvas, float posX, float posY);
}

创建一个标注View

你需要创建一个类去实现IMarker接口

public class YourMarkerView implements IMarker { ... }

根据你自己的需要去实现你所要实现的方法

下面例子的这种方法更简单,不需要实现IMarker接口提供的所有方法
只有特定的方法可以被覆盖和定制,最重要的是重写refreshContent方法来调整由标记绘制的数据

public class YourMarkerView extends MarkerView {

    private TextView tvContent;

    public MyMarkerView(Context context, int layoutResource) {
        super(context, layoutResource);

        // find your layout components
        tvContent = (TextView) findViewById(R.id.tvContent);
    }

    // callbacks everytime the MarkerView is redrawn, can be used to update the
    // content (user-interface)
    @Override
    public void refreshContent(Entry e, Highlight highlight) {

        tvContent.setText("" + e.getY());

        // this will perform necessary layouting
        super.refreshContent(e, highlight);
    }

    private MPPointF mOffset; 

    @Override
    public MPPointF getOffset() {

        if(mOffset == null) {
           // center the marker horizontally and vertically
           mOffset = new MPPointF(-(getWidth() / 2), -getHeight());
        }

        return mOffset;
    }
}

获取和设置标注对象

想要在图表中使用你设置好的marker,使用setMarker方法

IMarker marker = new YourMarkerView();
chart.setMarker(marker);

获取一个已经存在的marker,使用getMarker()方法

IMarker marker = chart.getMarker();

预置的标注




ChartData类 图表数据类

ChartData类是所有图表数据类的基类

public class LineData extends ChartData { ...

下面的是已经被实现且在子类中可以使用的方法

数据样式

获取数据

清空数据

高亮

动态数据

ChartData的子类

BarData

ScatterData

PieData

BubbleData




DataSet数据类

DataSet数据类用法与ChartData几乎一模一样

子类

Line-, Bar-, Scatter-, Bubble- & CandleDataSet

Line-, Bar-, Scatter-, Candle- & RadarDataSet

Line- & RadarDataSet

LineDataSet

BarDataSet

ScatterDataSet

CandleDataSet

BubbleDataSet

PieDataSet




ViewPortHandler 视窗控制

初始化

通过以下方式来获取视窗Handler实例

ViewPortHandler handler = chart.getViewPortHandler();

缩放和位移

图表尺寸和内容




FillFormatter接口 数据格式化

新建一个类实现FillFormatter接口

并重写下面这个方法

public float getFillLinePosition(LineDataSet dataSet, LineDataProvider provider)

可以实现单个的DataSet的实现在哪个位置停止绘制

public class MyCustomFillFormatter implements FillFormatter {

    @Override
    public float getFillLinePosition(LineDataSet dataSet, LineDataProvider dataProvider) {

        float myDesiredFillPosition = ...;
        // put your logic here...

        return myDesiredFillPosition;
    }
}

把格式化添加到图表中

lineDataSet.setFillFormatter(new MyCustomFillFormatter());

默认的实现---->DefaultFillFormatter.

上一篇下一篇

猜你喜欢

热点阅读