如何使用 MPAndroidChart 每 x 秒重绘一次图表?
How to redraw chart every x seconds with MPAndroidChart?
我有一个饼图 (MPAndroidChart) 通过 Volley 获取数据,我使用以下方法每 3 秒更新一次图表,但图表没有重新绘制。这都位于一个片段中,该片段显示在选项卡视图中。图表仅在我单击另一个选项卡并返回时刷新。当我在页面上时,它不会自行重绘。
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.activity_device_current_report, container, false);
new Handler().postDelayed(new Runnable(){
@Override
public void run() {
new AttemptJson().execute();
}
}, 3000);
return layout;
}
我有一个内在的class AttemptJson:
class AttemptJson extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... strings) {
updateChart();
return "";
}
}
这是我的 updateChart 方法,它获取 JSON 文件并使用 Volley 存储它。
private void updateChart() {
requestQueue = Volley.newRequestQueue(getContext());
JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, url,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray dataset = response.getJSONArray("dataset");
JSONArray time = response.getJSONArray("time");
JSONArray temp = dataset.getJSONObject(0).getJSONArray("data");
JSONArray humid = dataset.getJSONObject(1).getJSONArray("data");
for (int i = 0; i < temp.length(); i++) {
float temp_data = Float.parseFloat(temp.getJSONObject(i).getString("value"));
float time_data = Float.parseFloat(time.getJSONObject(i).getString("time"));
temperature.add(new Entry(time_data, temp_data));
}
float data = (float)(Float.parseFloat(humid.getJSONObject(humid.length()-1).getString("value")) + Math.random()*20 - 5);
if(humidity.size() != 0) humidity.clear();
humidity.add(new PieEntry(data));
humidity.add(new PieEntry(100 - data));
drawGraph();
} catch (JSONException e) {
Log.d("debug", "Object dataset is incorrect");
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(req);
}
在该方法中,我调用 drawGraph() 来绘制实际图形:
private void drawGraph() {
LineChart temperatureChart;
PieChart humidityChart;
LineDataSet lineDataSet1 = new LineDataSet(temperature, "temperature");
lineDataSet1.setDrawCircles(false);
lineDataSet1.setColor(Color.BLUE);
lineDataSet1.setDrawValues(false);
temperatureChart = (LineChart) getActivity().findViewById(R.id.curr_chart_temp);
humidityChart = (PieChart) getActivity().findViewById(R.id.curr_chart_humid);
temperatureChart.setData(new LineData(lineDataSet1));
temperatureChart.getAxisLeft().setAxisMinimum(-50f);
temperatureChart.getAxisLeft().setAxisMaximum(50f);
temperatureChart.getAxisRight().setEnabled(false);
temperatureChart.animateX(2000);
temperatureChart.setVisibleXRangeMaximum(400);
temperatureChart.invalidate();
PieDataSet dataset = new PieDataSet(humidity,"Humidity");
dataset.setColors(new int[]{Color.RED,Color.WHITE});
PieData humidValue= new PieData(dataset);
humidValue.setDrawValues(false);
humidityChart.setData(humidValue);
DecimalFormat df = new DecimalFormat("#.##");
humidityChart.setCenterText( df.format(humidity.get(0).getValue()) + "%");
humidityChart.setDrawCenterText(true);
humidityChart.animateY(1000);
}
在 Android 中,使用 findViewById
重复获取视图句柄作为函数局部变量并不是正确的方法。您当前的代码正在更新屏幕上显示的 LineChart
的单独实例。
改为创建 LineChart
和 PieChart
class 字段。
public class MyFragment extends Fragment {
private final LineChart lineChart;
private final PieChart pieChart;
public View onCreateView() {
View layout = inflater.inflate(R.layout.activity_device_current_report, container, false);
lineChart = layout.findViewById(R.id.curr_chart_temp);
pieChart = layout.findViewById(R.id.curr_chart_humid);
//insert the rest of your onCreate() code
}
}
然后在 updateChart()
中,除了 LineChart
、PieChart
和 findViewById
的声明之外,您可以使用其余代码。不要忘记在修改数据集后调用 notifyDatasetChanged()
。
我有一个饼图 (MPAndroidChart) 通过 Volley 获取数据,我使用以下方法每 3 秒更新一次图表,但图表没有重新绘制。这都位于一个片段中,该片段显示在选项卡视图中。图表仅在我单击另一个选项卡并返回时刷新。当我在页面上时,它不会自行重绘。
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.activity_device_current_report, container, false);
new Handler().postDelayed(new Runnable(){
@Override
public void run() {
new AttemptJson().execute();
}
}, 3000);
return layout;
}
我有一个内在的class AttemptJson:
class AttemptJson extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... strings) {
updateChart();
return "";
}
}
这是我的 updateChart 方法,它获取 JSON 文件并使用 Volley 存储它。
private void updateChart() {
requestQueue = Volley.newRequestQueue(getContext());
JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, url,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray dataset = response.getJSONArray("dataset");
JSONArray time = response.getJSONArray("time");
JSONArray temp = dataset.getJSONObject(0).getJSONArray("data");
JSONArray humid = dataset.getJSONObject(1).getJSONArray("data");
for (int i = 0; i < temp.length(); i++) {
float temp_data = Float.parseFloat(temp.getJSONObject(i).getString("value"));
float time_data = Float.parseFloat(time.getJSONObject(i).getString("time"));
temperature.add(new Entry(time_data, temp_data));
}
float data = (float)(Float.parseFloat(humid.getJSONObject(humid.length()-1).getString("value")) + Math.random()*20 - 5);
if(humidity.size() != 0) humidity.clear();
humidity.add(new PieEntry(data));
humidity.add(new PieEntry(100 - data));
drawGraph();
} catch (JSONException e) {
Log.d("debug", "Object dataset is incorrect");
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(req);
}
在该方法中,我调用 drawGraph() 来绘制实际图形:
private void drawGraph() {
LineChart temperatureChart;
PieChart humidityChart;
LineDataSet lineDataSet1 = new LineDataSet(temperature, "temperature");
lineDataSet1.setDrawCircles(false);
lineDataSet1.setColor(Color.BLUE);
lineDataSet1.setDrawValues(false);
temperatureChart = (LineChart) getActivity().findViewById(R.id.curr_chart_temp);
humidityChart = (PieChart) getActivity().findViewById(R.id.curr_chart_humid);
temperatureChart.setData(new LineData(lineDataSet1));
temperatureChart.getAxisLeft().setAxisMinimum(-50f);
temperatureChart.getAxisLeft().setAxisMaximum(50f);
temperatureChart.getAxisRight().setEnabled(false);
temperatureChart.animateX(2000);
temperatureChart.setVisibleXRangeMaximum(400);
temperatureChart.invalidate();
PieDataSet dataset = new PieDataSet(humidity,"Humidity");
dataset.setColors(new int[]{Color.RED,Color.WHITE});
PieData humidValue= new PieData(dataset);
humidValue.setDrawValues(false);
humidityChart.setData(humidValue);
DecimalFormat df = new DecimalFormat("#.##");
humidityChart.setCenterText( df.format(humidity.get(0).getValue()) + "%");
humidityChart.setDrawCenterText(true);
humidityChart.animateY(1000);
}
在 Android 中,使用 findViewById
重复获取视图句柄作为函数局部变量并不是正确的方法。您当前的代码正在更新屏幕上显示的 LineChart
的单独实例。
改为创建 LineChart
和 PieChart
class 字段。
public class MyFragment extends Fragment {
private final LineChart lineChart;
private final PieChart pieChart;
public View onCreateView() {
View layout = inflater.inflate(R.layout.activity_device_current_report, container, false);
lineChart = layout.findViewById(R.id.curr_chart_temp);
pieChart = layout.findViewById(R.id.curr_chart_humid);
//insert the rest of your onCreate() code
}
}
然后在 updateChart()
中,除了 LineChart
、PieChart
和 findViewById
的声明之外,您可以使用其余代码。不要忘记在修改数据集后调用 notifyDatasetChanged()
。