Android实现天气预报温度/气温折线趋势图
天气预报的APP应用中,难免会遇到绘制天气温度/气温,等关于数据趋势的折线或者曲线图,这类关于气温/温度的折线图,一般会有两条线,一条是高温线,一条是低温线。
我之前介绍了一个Android平台上第三方开源框架的统计图表库MPAndroidChart(文章链接地址:http://blog.csdn.net/zhangphil/article/details/47656521 ),具体使用方法详情请看这篇文章。
现在基于Android平台上的MPAndroidChart实现气温/温度折线图。
主Activity:MainActivity.java的全部代码:
package zhangphil.chart;
import java.text.DecimalFormat;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.Legend.LegendForm;
import com.github.mikephil.charting.components.Legend.LegendPosition;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.components.YAxis.AxisDependency;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.utils.ValueFormatter;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LineChart mChart = (LineChart) findViewById(R.id.chart);
setChart(mChart);
// 制作5个数据点。
setData(mChart, 5);
Legend l = mChart.getLegend();
l.setForm(LegendForm.LINE);
l.setTextSize(12f);
l.setTextColor(Color.BLACK);
l.setPosition(LegendPosition.BELOW_CHART_CENTER);
XAxis xAxis = mChart.getXAxis();
// 将X坐标轴的标尺刻度移动底部。
xAxis.setPosition(XAxisPosition.BOTTOM);
// X轴之间数值的间隔
xAxis.setSpaceBetweenLabels(1);
xAxis.setTextSize(12f);
xAxis.setTextColor(Color.BLACK);
YAxis leftAxis = mChart.getAxisLeft();
setYAxisLeft(leftAxis);
YAxis rightAxis = mChart.getAxisRight();
setYAxisRight(rightAxis);
}
private void setChart(LineChart mChart) {
mChart.setDescription("@ http://blog.csdn.net/zhangphil");
mChart.setNoDataTextDescription("如果传递的数值是空,那么你将看到这段文字。");
mChart.setHighlightEnabled(true);
mChart.setTouchEnabled(true);
mChart.setDragDecelerationFrictionCoef(0.9f);
mChart.setDragEnabled(true);
mChart.setScaleEnabled(true);
mChart.setDrawGridBackground(true);
mChart.setHighlightPerDragEnabled(true);
mChart.setPinchZoom(true);
mChart.setBackgroundColor(Color.LTGRAY);
mChart.animateX(3000);
}
private void setYAxisLeft(YAxis leftAxis) {
// 在左侧的Y轴上标出4个刻度值
leftAxis.setLabelCount(4, true);
// Y坐标轴轴线的颜色
leftAxis.setGridColor(Color.RED);
// Y轴坐标轴上坐标刻度值的颜色
leftAxis.setTextColor(Color.RED);
// Y坐标轴最大值
leftAxis.setAxisMaxValue(50);
// Y坐标轴最小值
leftAxis.setAxisMinValue(10);
leftAxis.setStartAtZero(false);
leftAxis.setDrawLabels(true);
}
private void setYAxisRight(YAxis rightAxis) {
// Y坐标轴上标出8个刻度值
rightAxis.setLabelCount(8, true);
// Y坐标轴上刻度值的颜色
rightAxis.setTextColor(Color.BLUE);
// Y坐标轴上轴线的颜色
rightAxis.setGridColor(Color.BLUE);
// Y坐标轴最大值
rightAxis.setAxisMaxValue(30);
// Y坐标轴最小值
rightAxis.setAxisMinValue(-5);
rightAxis.setStartAtZero(false);
rightAxis.setDrawLabels(true);
}
private void setData(LineChart mChart, int count) {
ArrayList<String> xVals = new ArrayList<String>();
for (int i = 0; i < count; i++) {
xVals.add("某月" + (i + 1) + "日");
}
ArrayList<Entry> yHigh = new ArrayList<Entry>();
LineDataSet high = new LineDataSet(yHigh, "高温");
setHighTemperature(high, yHigh, count);
ArrayList<Entry> yLow = new ArrayList<Entry>();
LineDataSet low = new LineDataSet(yLow, "低温");
setLowTemperature(low, yLow, count);
ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();
dataSets.add(high);
dataSets.add(low);
LineData data = new LineData(xVals, dataSets);
data.setValueTextColor(Color.DKGRAY);
data.setValueTextSize(10f);
mChart.setData(data);
}
private void setHighTemperature(LineDataSet high, ArrayList<Entry> yVals,
int count) {
for (int i = 0; i < count; i++) {
float val = (float) Math.random() + 30;
yVals.add(new Entry(val, i));
}
// 以左边的Y坐标轴为准
high.setAxisDependency(AxisDependency.LEFT);
high.setLineWidth(5f);
high.setColor(Color.RED);
high.setCircleSize(8f);
high.setCircleColor(Color.YELLOW);
high.setCircleColorHole(Color.DKGRAY);
high.setDrawCircleHole(true);
// 设置折线上显示数据的格式。如果不设置,将默认显示float数据格式。
high.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
DecimalFormat decimalFormat = new DecimalFormat(".0");
String s = "高温" + decimalFormat.format(value);
return s;
}
});
}
private void setLowTemperature(LineDataSet low, ArrayList<Entry> yVals,
int count) {
for (int i = 0; i < count; i++) {
float val = (float) Math.random() + 5;
yVals.add(new Entry(val, i));
}
// 以右边Y坐标轴为准
low.setAxisDependency(AxisDependency.RIGHT);
// 折现的颜色
low.setColor(Color.GREEN);
// 线宽度
low.setLineWidth(3f);
// 折现上点的圆球颜色
low.setCircleColor(Color.BLUE);
// 填充圆球中心部位洞的颜色
low.setCircleColorHole(Color.LTGRAY);
// 圆球的尺寸
low.setCircleSize(5f);
low.setDrawCircleHole(true);
low.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
DecimalFormat decimalFormat = new DecimalFormat(".0");
String s = "低温" + decimalFormat.format(value);
return s;
}
});
}
}
MainActivity.java需要的布局文章activity_main.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
运行结果如图:
需要对MPAndroidChart的坐标体系加以说明。MPAndroidChart的Y纵坐标轴分为左右两条纵坐标:左纵坐标轴(chart的getAxisLeft()获得的YAxis)和右纵坐标轴(chart的getAxisRight()获得的YAxis)。虽然它们都是MPAndroidChart中的Yaxis一个类代表,但它们在具体使用中是相互独立的,但它们共用X坐标轴(横坐标)。
比如在本例中,左边的红色Y纵坐标轴独立代表高温折线,它有自己独立运行的一套绘图机制;同理,右边蓝色Y纵坐标轴独立代表的低温折线,它也有自己独立运行的一套绘图机制。不要将两者混为一谈。