目录
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
Step 1:在布局中添加折线图控件
Step 2:声明控件
private LineChart lc;
Step 3:获取控件
Lc = (LineChart) findViewById(R.id.lc);
< 1 > 实现步骤
①、获取一或多组Entry对象集合的数据(List
②、分别通过每一组Entry对象的集合数据创建折线数据集(LineDataSet);
③、将每一组折线数据集添加到折线数据(LineData)中;
④、将折现数据设置给图表
< 2 > 设置一组数据
这里我模拟一组“最高气温”的数据为例。
>> 代码:
// 1. 获取一或多组Entry对象集合的数据
// 模拟数据1
List 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 yVals1 = new ArrayList<>();
float[] ys1 = new float[] {22f, 24f, 25f, 25f, 25f, 22f};
// 模拟数据2
List 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 dataSets = new ArrayList<>();
//dataSets.add(lineDataSet1);
//dataSets.add(lineDataSet2);
//LineData lineData = new LineData(dataSets);
// 4.将折线数据设置给图表
lc.setData(lineData);
>> 效果图:
< 1 > 圆点
>> 相关方法:
返回类型 |
方法 |
描述 |
默认 |
void |
setCircleColor(int color) |
设置点所有圆的颜色 |
rgb(140,234,255) |
void |
setCircleColors (int… colors) |
设置圆点的颜色(参数不限) |
|
void |
setCircleColors (int[] colors, Context c) |
设置圆点的颜色(更加id从colors资源文件中获取) |
|
void |
setCircleColors (List |
设置圆点的颜色 |
|
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 |
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
>> 效果图:
>> 代码:
// 值的字体大小为12dp
lineData.setValueTextSize(12f);
// 值的格式
lineData.setValueFormatter(new IValueFormatter() {
@Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
return (int) entry.getY() + "℃";
}
});
>> 效果图:
>> 代码:
// 左边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); // 不启用
>> 效果图:
>> 代码:
// 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];
}
});
>> 效果图:
>> 代码:
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 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);
}
>> 效果图:
>> 代码:
lineDataSet1.setDrawFilled(true); // 启用填充
lineDataSet1.setFillColor(Color.WHITE); // 填充白色
lineDataSet1.setFillAlpha(65); // 透明度
>> 效果图:
>> 代码:
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() {}
});
>> 效果图: