MPAndroidChart3使用详解3:LineChar(折线图)

目录

 

1 简述

2 使用说明

2.1 使用

2.2 设置数据

2.3 折线数据集设置样式(LineDataSet)

2.4 折线数据设置样式(LineData)

2.5 Y轴(YAxis)

2.5 X轴(XAxis)

2.6 综合案例

2.7 填充

2.8 Maker


1 简述

 

2 使用说明

2.1 使用

Step 1:在布局中添加折线图控件

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

Step 2:声明控件

private LineChart lc;

Step 3:获取控件

Lc = (LineChart) findViewById(R.id.lc);

2.2 设置数据

< 1 > 实现步骤

 ①、获取一或多组Entry对象集合的数据(List<Entry>);

 ②、分别通过每一组Entry对象的集合数据创建折线数据集(LineDataSet);

 ③、将每一组折线数据集添加到折线数据(LineData)中;

 ④、将折现数据设置给图表

< 2 > 设置一组数据

    这里我模拟一组“最高气温”的数据为例。

>> 代码:

// 1. 获取一或多组Entry对象集合的数据
// 模拟数据1
List<Entry> yVals1 = new ArrayList<>();
float[] ys1 = new float[] {22f, 24f, 25f, 25f, 25f, 22f};
for (int i = 0; i < ys1.length; i++) {
     yVals1.add(new Entry(i,ys1[i])); 
}
// 2. 分别通过每一组Entry对象集合的数据创建折线数据集
LineDataSet lineDataSet1 = new LineDataSet(yVals1, "最高温度");
// 3. 将每一组折线数据集添加到折线数据中
LineData lineData = new LineData(lineDataSet1);
// 4. 将折线数据设置给图表
lc.setData(lineData);

>> 效果图:

 

< 3 >设置多组数据

    在前面模拟一组“最高气温”的数据基础上,再模拟一组“最低气温”的数据。

>> 代码:

// 1.获取一或多组Entry对象集合的数据
// 模拟数据1
List<Entry> yVals1 = new ArrayList<>();
float[] ys1 = new float[] {22f, 24f, 25f, 25f, 25f, 22f};
// 模拟数据2
List<Entry> yVals2 = new ArrayList<>();
float[] ys2 = new float[] {14f, 15f, 16f, 17f, 16f, 16f};
for (int i = 0; i < ys1.length; i++) {
    yVals1.add(new Entry(i,ys1[i]));
    yVals2.add(new Entry(i,ys2[i]));
}
// 2.分别通过每一组Entry对象集合的数据创建折线数据集
LineDataSet lineDataSet1 = new LineDataSet(yVals1, "最高温度");
LineDataSet lineDataSet2 = new LineDataSet(yVals2, "最低温度");
// 3将每一组折线数据集添加到折线数据中
LineData lineData = new LineData(
        lineDataSet1,
        lineDataSet2
);
// 或者
//List<ILineDataSet> dataSets = new ArrayList<>();
//dataSets.add(lineDataSet1);
//dataSets.add(lineDataSet2);
//LineData lineData = new LineData(dataSets);
// 4.将折线数据设置给图表
lc.setData(lineData);

>> 效果图:

2.3 折线数据集设置样式(LineDataSet)

< 1 > 圆点

>> 相关方法:

返回类型

方法

描述

默认

void

setCircleColor(int color)

设置点所有圆的颜色

rgb(140,234,255)

void

setCircleColors (int… colors)

设置圆点的颜色(参数不限)

 

void

setCircleColors (int[] colors, Context c)

设置圆点的颜色(更加id从colors资源文件中获取)

 

void

setCircleColors (List<Integer> colors)

设置圆点的颜色

 

void

setCircleRadius(float radius)

设置圆点的半径(单位:dp),最小1dp

4dp

void

setCircleSize(float size)

设置圆点的半径(单位:dp)最小1dp(弃用)

4dp

void

setDrawCircle (boolean enabled)

设置是否绘制圆点

true

void

resetCircleColors ()

重置圆点颜色

 

int

getCircleColor (int index)

获取圆点中指定位置的颜色

 

int

getCircleColorCount ()

获取圆点颜色集合的数量

 

List<Integer>

getCircleColors ()

获取圆点颜色集合

 

float

getCircleRadius ()

获取圆点半径

4dp

float

getCircleSize ()

获取圆点半径(弃用)

4dp

boolean

isDrawCircleEnabled()

是否绘制圆点

true

< 2 > 圆洞

>> 相关方法:

返回类型

方法

描述

默认

void

setCircleHoleRadius(float holeRadius)

设置圆洞的半径,最小为0.5dp

2dp

void

setCircleColorHole(int color)

设置圆洞的颜色

白色

void

setDrawCircleHole (boolean enabled)

设置是否绘制圆洞

true

float

getCircleHoleRadius()

获取圆洞的半径

2dp

int

getCircleHoleColor()

获取圆洞的颜色

白色

boolean

isDrawCircleHoleEnabled ()

是否绘制圆洞

true

< 3 > 圆点与圆洞的应用:

>> 代码:

lineDataSet1.setDrawCircleHole(false); // 不绘制圆洞,即为实心圆点
lineDataSet1.setColor(Color.RED); // 设置为红色,第二组为蓝色
lineDataSet1.setCircleColor(Color.RED); // 设置圆点为颜色,第二组为蓝色
lineDataSet1.setLineWidth(2f); // 设置线宽为2

>> 效果图:

2.4 折线数据设置样式(LineData)

>> 代码:

// 值的字体大小为12dp
lineData.setValueTextSize(12f);
// 值的格式
lineData.setValueFormatter(new IValueFormatter() {
    @Override
    public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
        return (int) entry.getY() + "℃";
    }
});

>> 效果图:

2.5 Y轴(YAxis)

>> 代码:

// 左边Y轴
YAxis yAxisLeft = lc.getAxisLeft();
yAxisLeft.setDrawAxisLine(false); // 不绘制Y轴
yAxisLeft.setDrawLabels(false); // 不绘制标签
yAxisLeft.setAxisMaximum(26.5f); // 设置Y轴最大值
yAxisLeft.setAxisMinimum(14f); // 设置Y轴最小值
yAxisLeft.setGranularity(3f); // 设置间隔尺寸
// 右侧Y轴
lc.getAxisRight().setEnabled(false); // 不启用

>> 效果图:

2.5 X轴(XAxis)

>> 代码:

// X轴
XAxis xAxis = lc.getXAxis();
xAxis.setDrawAxisLine(false); // 不绘制X轴
xAxis.setDrawGridLines(false); // 不绘制网格线
// 模拟X轴标签数据
final String[] weekStrs = new String[]{"昨天", "今天", "明天", "周五", "周六", "周日"};
xAxis.setLabelCount(weekStrs.length); // 设置标签数量
xAxis.setTextColor(Color.GRAY); // 文本颜色为灰色
xAxis.setTextSize(18f); // 文本大小为18dp
xAxis.setGranularity(1f); // 设置间隔尺寸
// 使图表左右留出点空位
xAxis.setAxisMinimum(-0.1f); // 设置X轴最小值
xAxis.setAxisMaximum(5.1f); // 设置X轴最大值
// 设置标签的显示格式
xAxis.setValueFormatter(new IAxisValueFormatter() {
    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        return weekStrs[(int) value];
    }
});

>> 效果图:

2.6 综合案例

>> 代码:

private LineChart lc;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_line_chart);
    initView();
    initData();
}

private void initView() {
    lc = (LineChart) findViewById(R.id.lc);
}

private void initData() {
    // 设置上下左右偏移量
    lc.setExtraOffsets(24f,24f,24f,0f);
    lc.setBackgroundColor(Color.parseColor("#0f0f0f"));
    setDescription("过去一分钟的气温变化"); // 设置描述
    lc.animateXY(3000, 3000); // XY动画
    setLegend(); // 设置图例
    setYAxis(); // 设置Y轴
    setXAxis(); // 设置X轴
    setChartData(); // 设置图标数据
}

private void setLegend() {
    Legend legend = lc.getLegend();
    legend.setForm(Legend.LegendForm.LINE); // 图形:线
    legend.setFormSize(14f); // 图形大小
    legend.setFormLineWidth(9f); // 线宽小于如下大小绘制出平躺长方形
    legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT); // 图例在水平线上的对齐方式:右对齐
    legend.setTextColor(Color.WHITE);
}

private void setDescription(String descriptionStr) {
    // 设置描述
    Description description = new Description();
    description.setText(descriptionStr);
    // 计算描述位置
    WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics outMetrics = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(outMetrics);
    Paint paint = new Paint();
    paint.setTextSize(16f);
    float x = outMetrics.widthPixels - Utils.convertDpToPixel(12);
    float y =  Utils.calcTextHeight(paint, descriptionStr) + Utils.convertDpToPixel(12);
    description.setPosition(x, y); // 设置描述位置
    lc.setDescription(description);
}

private void setYAxis() {
    // 左边Y轴
    final YAxis yAxisLeft = lc.getAxisLeft();
    yAxisLeft.setAxisMaximum(25.5f); // 设置Y轴最大值
    yAxisLeft.setAxisMinimum(14); // 设置Y轴最小值
    yAxisLeft.setGranularity(2f); // 设置间隔尺寸
    yAxisLeft.setTextSize(12f); // 文本大小为12dp
    yAxisLeft.setTextColor(Color.WHITE); // 文本颜色为灰色
    yAxisLeft.setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return value == yAxisLeft.getAxisMinimum() ? (int) value + "" : (int) value +"";
        }
    });
    // 右侧Y轴
    lc.getAxisRight().setEnabled(false); // 不启用
}

private void setXAxis() {
    // X轴
    XAxis xAxis = lc.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); // 在底部
    xAxis.setDrawGridLines(false); // 不绘制网格线
    xAxis.setLabelCount(20); // 设置标签数量
    xAxis.setTextColor(Color.WHITE); // 文本颜色为灰色
    xAxis.setTextSize(12f); // 文本大小为12dp
    xAxis.setGranularity(3f); // 设置间隔尺寸
    xAxis.setAxisMinimum(0f); // 设置X轴最小值
    xAxis.setAxisMaximum(63f); // 设置X轴最大值
    // 设置标签的显示格式
    xAxis.setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return value == 0 ? "℃" : value == 63 ? "(S)" : value < 10 ? "0" + (int) value : (int) value + "";
        }
    });
}

public void setChartData() {
    // 1.获取一或多组Entry对象集合的数据
    // 模拟数据1
    List<Entry> yVals1 = new ArrayList<>();
    float[] ys1 = new float[] {
            19f, 19f, 18f, 18f, 18f, 18f, 17f, 16f, 17f, 19f,
            21f, 21f, 23f, 23f, 24f, 24f, 25f, 25f, 25f, 24f};
    for (int i = 0; i < ys1.length; i++) {
        yVals1.add(new Entry((i + 1) * 3,ys1[i]));
    }

    // 2.分别通过每一组Entry对象集合的数据创建折线数据集
    LineDataSet lineDataSet1 = new LineDataSet(yVals1, "温度");
    lineDataSet1.setDrawCircleHole(false); // 不绘制圆洞,即为实心圆点
    lineDataSet1.setColor(Color.WHITE); // 设置为红色
    lineDataSet1.setMode(LineDataSet.Mode.CUBIC_BEZIER); // 设置为贝塞尔曲线
    lineDataSet1.setCubicIntensity(0.15f); // 强度
    lineDataSet1.setCircleColor(Color.WHITE); // 设置圆点为颜色
    lineDataSet1.setCircleRadius(5f);
    lineDataSet1.setLineWidth(2f); // 设置线宽为2
    // 3.将每一组折线数据集添加到折线数据中
    LineData lineData = new LineData(lineDataSet1);
    lineData.setDrawValues(false);
    // 4.将折线数据设置给图表
    lc.setData(lineData);
}

>> 效果图:

2.7 填充

>> 代码:

lineDataSet1.setDrawFilled(true); // 启用填充
lineDataSet1.setFillColor(Color.WHITE); // 填充白色
lineDataSet1.setFillAlpha(65); // 透明度

>> 效果图:

2.8 Maker

>> 代码:

    Step 1:自定义Maker

public class TMarket implements IMarker {

    private Entry mEntry;

    @Override
    public MPPointF getOffset() {
        return null;
    }

    @Override
    public MPPointF getOffsetForDrawingAtPoint(float posX, float posY) {
        return null;
    }

    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        this.mEntry = e;
    }

    @Override
    public void draw(Canvas canvas, float posX, float posY) {
        Paint paint = new Paint();
        paint.setColor(Color.YELLOW);
        // 绘制倒等腰三角线
        Path path = new Path();
        path.moveTo(posX, posY - Utils.convertDpToPixel(5));
        path.lineTo(posX - Utils.convertDpToPixel(8), posY - Utils.convertDpToPixel(18));
        path.lineTo(posX + Utils.convertDpToPixel(8), posY - Utils.convertDpToPixel(18));
        path.close();
        canvas.drawPath(path, paint);
        // 绘制矩形
        RectF rect = new RectF(
                posX - Utils.convertDpToPixel(24),
                posY - Utils.convertDpToPixel(41),
                posX + Utils.convertDpToPixel(24),
                posY - Utils.convertDpToPixel(17));
        canvas.drawRect(rect, paint);
        // 绘制文字,居于矩形框正中间
        if (mEntry != null) {
            String str = String.valueOf(mEntry.getY());
            Paint textPaint = new Paint();
            textPaint.setColor(Color.RED);
            textPaint.setTextSize(Utils.convertDpToPixel(18));
            textPaint.setTypeface(Typeface.DEFAULT_BOLD); 
            canvas.drawText(str,
                    // x = 矩形左坐标 + (矩形宽度 - 文本宽度)/ 2
                    rect.left + (Utils.convertDpToPixel(48) - Utils.calcTextWidth(textPaint, str)) / 2,
                    // y = 矩形下坐标 + (矩形高度 - 文本高度)/ 2
                    rect.bottom - (Utils.convertDpToPixel(24) - Utils.calcTextHeight(textPaint, str)) / 2,
                    textPaint);
        }
    }
}

    Step 2:应用定制的Maker

final TMarket tMarket = new TMarket();
lc.setMarker(tMarket);
lc.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
    @Override
    public void onValueSelected(Entry e, Highlight h) {
        tMarket.refreshContent(e, h);
    }

    @Override
    public void onNothingSelected() {}
});

>> 效果图:

  • 15
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Homilier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值