使用 MPAndroidChart 绘制时间序列图
我想在 Android 中绘制时间序列数据。 我有一个温度传感器,每 10 秒报告一次数据。我正在使用 API 从云中获取这些数据。 在数据中,我有一个温度值及其时间戳。 我想显示 1 个月的数据,用户可以缩放图表直到时间戳(直到秒或分钟)。
我尝试使用 MPAndroidChart 进行绘图。我在 X 轴上取了时间戳,在 Y 轴上取了值。 MPAndroidChart 只允许浮点值,并且我有长类型的时间戳。 因此,我将第一个起始时间戳记为 0,并通过从中减去这个基本时间戳来计算其他时间戳。 我在读完这个问题后就这样做了。 https://github.com/PhilJay/MPAndroidChart/issues/2891
我用过这个问题。 这是我的代码片段。
private void showChart(ArrayList<TempData> tempData, long baseTimestamp) {
// Prepare Bar Entries
ArrayList<BarEntry> barEntries = new ArrayList<>();
for (int i = 0; i < tempData.size(); i++) {
long timestamp = tempData.getTimestamp(); // Here timestamp & baseTimestamp both are in seconds.
timestamp = timestamp - baseTimestamp;
Log.d(TAG, "Adding entry with timestamp : " + timestamp);
BarEntry barEntry = new BarEntry(timestamp, tempData.get(i).getValue());
barEntries.add(barEntry);
}
// Initialise xAxis
XAxis xAxis = barChart.getXAxis();
xAxis.enableGridDashedLine(10f, 10f, 0f);
xAxis.setTextColor(Color.BLACK);
xAxis.setTextSize(14);
xAxis.setDrawAxisLine(true);
xAxis.setAxisLineColor(Color.BLACK);
xAxis.setDrawGridLines(true);
xAxis.setGranularity(1f);
xAxis.setGranularityEnabled(true);
xAxis.setAxisMinimum(0 + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
xAxis.setAxisMaximum(barEntries.size() + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
// xAxis.setLabelCount(xAxisLabel.size(), true); //draw x labels for 13 vertical grid lines
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setXOffset(0f); //labels x offset in dps
xAxis.setYOffset(0f); //labels y offset in dps
xAxis.setCenterAxisLabels(true);
xAxis.setValueFormatter(new TimestampXAxisFormatter(baseTimestamp));
// xAxis.setLabelCount(4);
// Initialize Y-Right-Axis
YAxis rightAxis = barChart.getAxisRight();
rightAxis.setTextColor(Color.BLACK);
rightAxis.setTextSize(14);
rightAxis.setDrawAxisLine(true);
rightAxis.setAxisLineColor(Color.BLACK);
rightAxis.setDrawGridLines(true);
rightAxis.setGranularity(1f);
rightAxis.setGranularityEnabled(true);
rightAxis.setAxisMinimum(0);
rightAxis.setAxisMaximum(1000f);
rightAxis.setLabelCount(4, true); //draw y labels (Y-Values) for 4 horizontal grid lines starting from 0 to 1000f
rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
//initialize Y-Left-Axis
YAxis leftAxis = barChart.getAxisLeft();
leftAxis.setAxisMinimum(0);
leftAxis.setDrawAxisLine(true);
leftAxis.setLabelCount(0, true);
leftAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return "";
}
});
// set the BarDataSet
BarDataSet barDataSet = new BarDataSet(barEntries, "Time Series");
barDataSet.setColor(Color.RED);
barDataSet.setFormSize(15f);
barDataSet.setDrawValues(false);
barDataSet.setValueTextSize(12f);
// set the BarData to chart
BarData data = new BarData(barDataSet);
barChart.setData(data);
barChart.setScaleEnabled(false);
barChart.getLegend().setEnabled(false);
barChart.setDrawBarShadow(false);
barChart.getDescription().setEnabled(false);
barChart.setPinchZoom(false);
barChart.setDrawGridBackground(true);
barChart.invalidate();
}
class TimestampXAxisFormatter extends IndexAxisValueFormatter {
long baseTimestamp;
TimestampXAxisFormatter(long baseTime) {
baseTimestamp = baseTime;
}
@Override
public String getFormattedValue(float value) {
// Add base timestamp
long timestamp = (long) value;
timestamp = timestamp + baseTimestamp;
Log.d(TAG, "getFormattedValue, value : " + value);
Log.e(TAG, "getFormattedValue, Timestamp : " + timestamp);
// Convert from seconds back to milliseconds to format time to show to the user
String dateTimeInStr = new SimpleDateFormat("HH:mm:ss").format(new Date(timestamp * 1000));
return dateTimeInStr;
}
}
我期待 TimestampXAxisFormatter 的“getFormattedValue”方法中的时间戳(用于添加 BarEntry 的时间戳差异)。 但我得到了 0.0、2.0、4.0、6.0 等。 由于我无法在“getFormattedValue”方法中接收时间戳,这里有什么错误?
请任何人帮助我找出问题并绘制 1 个月的数据,用户将能够缩放到几秒钟。
提前致谢。
I want to plot time series data in Android.
I have a temperature sensor which reports data at every 10 seconds. I am taking that data from cloud using API.
In data, I have a temperature value and its timestamp.
I want to display data for 1 month and user can zoom chart till timestamp (till seconds or mins).
I tried to plot using MPAndroidChart. I have taken timestamps on X-axis and value on Y-axis.
MPAndroidChart only allows float values and I have timestamps which are of long type.
So I have taken first starting timestamp as 0 and calculated others by subtracting this base timestamp from it.
I have done this after reading this issue. https://github.com/PhilJay/MPAndroidChart/issues/2891
I have used code from answer of this question.
Here is my code snippet.
private void showChart(ArrayList<TempData> tempData, long baseTimestamp) {
// Prepare Bar Entries
ArrayList<BarEntry> barEntries = new ArrayList<>();
for (int i = 0; i < tempData.size(); i++) {
long timestamp = tempData.getTimestamp(); // Here timestamp & baseTimestamp both are in seconds.
timestamp = timestamp - baseTimestamp;
Log.d(TAG, "Adding entry with timestamp : " + timestamp);
BarEntry barEntry = new BarEntry(timestamp, tempData.get(i).getValue());
barEntries.add(barEntry);
}
// Initialise xAxis
XAxis xAxis = barChart.getXAxis();
xAxis.enableGridDashedLine(10f, 10f, 0f);
xAxis.setTextColor(Color.BLACK);
xAxis.setTextSize(14);
xAxis.setDrawAxisLine(true);
xAxis.setAxisLineColor(Color.BLACK);
xAxis.setDrawGridLines(true);
xAxis.setGranularity(1f);
xAxis.setGranularityEnabled(true);
xAxis.setAxisMinimum(0 + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
xAxis.setAxisMaximum(barEntries.size() + 0.5f); //to center the bars inside the vertical grid lines we need + 0.5 step
// xAxis.setLabelCount(xAxisLabel.size(), true); //draw x labels for 13 vertical grid lines
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setXOffset(0f); //labels x offset in dps
xAxis.setYOffset(0f); //labels y offset in dps
xAxis.setCenterAxisLabels(true);
xAxis.setValueFormatter(new TimestampXAxisFormatter(baseTimestamp));
// xAxis.setLabelCount(4);
// Initialize Y-Right-Axis
YAxis rightAxis = barChart.getAxisRight();
rightAxis.setTextColor(Color.BLACK);
rightAxis.setTextSize(14);
rightAxis.setDrawAxisLine(true);
rightAxis.setAxisLineColor(Color.BLACK);
rightAxis.setDrawGridLines(true);
rightAxis.setGranularity(1f);
rightAxis.setGranularityEnabled(true);
rightAxis.setAxisMinimum(0);
rightAxis.setAxisMaximum(1000f);
rightAxis.setLabelCount(4, true); //draw y labels (Y-Values) for 4 horizontal grid lines starting from 0 to 1000f
rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
//initialize Y-Left-Axis
YAxis leftAxis = barChart.getAxisLeft();
leftAxis.setAxisMinimum(0);
leftAxis.setDrawAxisLine(true);
leftAxis.setLabelCount(0, true);
leftAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return "";
}
});
// set the BarDataSet
BarDataSet barDataSet = new BarDataSet(barEntries, "Time Series");
barDataSet.setColor(Color.RED);
barDataSet.setFormSize(15f);
barDataSet.setDrawValues(false);
barDataSet.setValueTextSize(12f);
// set the BarData to chart
BarData data = new BarData(barDataSet);
barChart.setData(data);
barChart.setScaleEnabled(false);
barChart.getLegend().setEnabled(false);
barChart.setDrawBarShadow(false);
barChart.getDescription().setEnabled(false);
barChart.setPinchZoom(false);
barChart.setDrawGridBackground(true);
barChart.invalidate();
}
class TimestampXAxisFormatter extends IndexAxisValueFormatter {
long baseTimestamp;
TimestampXAxisFormatter(long baseTime) {
baseTimestamp = baseTime;
}
@Override
public String getFormattedValue(float value) {
// Add base timestamp
long timestamp = (long) value;
timestamp = timestamp + baseTimestamp;
Log.d(TAG, "getFormattedValue, value : " + value);
Log.e(TAG, "getFormattedValue, Timestamp : " + timestamp);
// Convert from seconds back to milliseconds to format time to show to the user
String dateTimeInStr = new SimpleDateFormat("HH:mm:ss").format(new Date(timestamp * 1000));
return dateTimeInStr;
}
}
I was expecting timestamp (timestamp difference which was used to add BarEntry) in "getFormattedValue" method of TimestampXAxisFormatter.
But I am getting 0.0, 2.0, 4.0, 6.0 etc.
What is the mistake here because of that I am not able to receive timestamp in "getFormattedValue" method?
Anyone please help me to find out the issue and plot 1 month of data and user will be able to zoom till seconds.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你想要在x轴上显示的值,首先添加到数组列表中,如下所示
这里我制作了一个年份图。
然后,当我们初始化 X 轴时,我们可以使用
.setValueFormatter()
函数设置值,如下所示:-在您的情况下,您尝试将值转换为
中的时间戳>getFormattedValue()
是 1.0,2.0。等等,这就是你没有获得你想要的价值的原因。
现在,当您想每 10 秒显示一次数据时,方法如下 -
为了每 10 秒显示一次数据,我们需要相应地添加 xLabel:-
然后使用下面的代码在 XAxis 中设置它:-
The value you want to show in x-axis,first add in Array list as below
Here I had made a Year Graph.
Then when we are initializing the X -axis, There we can set value by using
.setValueFormatter()
function as shown below :-In your case, the value which you try to convert into timestamp in
getFormattedValue()
is 1.0,2.0. etc, Thats the reason you are not geting the value as you want.
Now as You want to show data in every 10 sec, Here is the way -
For Showing the data in every 10 secs, we need to add xLabel accordingly :-
and then setting it in XAxis using below code :-