天天看點

Android實作天氣預報溫度/氣溫折線趨勢圖



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縱坐标軸獨立代表的低溫折線,它也有自己獨立運作的一套繪圖機制。不要将兩者混為一談。

繼續閱讀