我正在处理两个不同的图表,一个是RadarChart,用于将“评估”中的所有“类别”的得分与其他“评估”进行比较,另一个是分组的BarChart,允许用户在一个图表中选择“类别”。 “评估”,并将其与其他“评估”进行比较。从Firebase提取数据,并将DatabaseReferences
存储在ArrayList
中。我的RadarChart使用以下代码并显示以下结果:
ArrayList<RadarDataSet> dataSets = new ArrayList<>();
ArrayList<IRadarDataSet> allDataSets = new ArrayList<>();
for(int i = 0; i < assessmentKeys.size(); i++) {
final ArrayList<RadarEntry> radarEntries = new ArrayList<>();
final int trackerIndex = i;
dataSets.add(trackerIndex, new RadarDataSet(radarEntries, assessmentName.get(i)) );
mAssessmentCategoryRefs.get(i).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Category category = postSnapshot.getValue(Category.class);
radarEntries.add(new RadarEntry((float)category.getCategoryScore(), category.getNumber() - 1));
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Random random = new Random();
int randomR = random.nextInt(256);
int randomG = random.nextInt(256);
int randomB = random.nextInt(256);
dataSets.get(trackerIndex).setColor(Color.rgb(randomR, randomG, randomB));
dataSets.get(trackerIndex).setFillColor(Color.rgb(randomR, randomG, randomB));
dataSets.get(trackerIndex).setDrawFilled(true);
allDataSets.add(dataSets.get(trackerIndex));
}
RadarData data = new RadarData(allDataSets);
由于RadarEntry
,BarEntry
,BarDataSet
,RadarDataSet
,IBarDataSet
和IRadarDataSet
在它们之间共享父类,因此我认为我将能够以与RadarChart相同的方式将数据加载到分组的BarChart中。为了进行概念验证,我使用以下代码在尝试从Firebase中拉出之前验证它是否可以工作:
final ArrayList<BarDataSet> dataSets = new ArrayList<>();
ArrayList<IBarDataSet> allDataSets = new ArrayList<>();
for(int j = 0; j < assessmentKeys.size(); j++ ) {
final int jTracker = j;
final ArrayList<BarEntry> entries = new ArrayList<>();
dataSets.add(j, new BarDataSet(entries, assessmentName.get(j)));
Log.d("Received_Data", "Getting data for " + assessmentName.get(j));
for(int k = 0; k < categoryNames.size(); k++) {
entries.add(new BarEntry(k, k+1));
}
Random random = new Random();
int randomR = random.nextInt(256);
int randomG = random.nextInt(256);
int randomB = random.nextInt(256);
dataSets.get(j).setColor(Color.rgb(randomR, randomG, randomB));
allDataSets.add(dataSets.get(j));
}
这产生了这张图:
当我添加要从Firebase中提取的代码时,RadarChart不会发生奇怪的事情:
final ArrayList<BarDataSet> dataSets = new ArrayList<>();
ArrayList<IBarDataSet> allDataSets = new ArrayList<>();
for(int j = 0; j < assessmentKeys.size(); j++ ) {
final int jTracker = j;
final ArrayList<BarEntry> entries = new ArrayList<>();
dataSets.add(j, new BarDataSet(entries, assessmentName.get(j)));
Log.d("Received_Data", "Getting data for " + assessmentName.get(j));
for(int k = 0; k < categoryNames.size(); k++) {
final String categoryName = categoryNames.get(k);
final int kTracker = k;
mAssessmentCategoryRefs.get(jTracker).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for(DataSnapshot postSnapShot : dataSnapshot.getChildren()) {
Category category = postSnapShot.getValue(Category.class);
if(categoryName.equals(category.getName())) {
entries.add(new BarEntry(kTracker, (float)category.getCategoryScore()));
Log.d(TAG, "Added " + category.getName() + " to entries");
} else {
Log.d(TAG, "Skipped " + category.getName());
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Random random = new Random();
int randomR = random.nextInt(256);
int randomG = random.nextInt(256);
int randomB = random.nextInt(256);
dataSets.get(j).setColor(Color.rgb(randomR, randomG, randomB));
allDataSets.add(dataSets.get(j));
}
BarData data = new BarData(allDataSets);
mBarChart.setData(data);
data.notifyDataChanged();
mBarChart.notifyDataSetChanged();
mBarChart.invalidate();
即使我的日志显示该数据正确地跳过了与所选名称不匹配的类别,也没有添加该类别的分数,即使我的日志显示该数据也没有。
这是什么原因?起初,我认为这可能是由于从Firebase提取数据的异步特性造成的,但是如果是这种情况,我的RadarChart也会遇到同样的问题。据我所知RadarEntry
和BarEntry
之间的唯一真正区别是,索引是RadarEntry
中的第二个参数,但是BarEntry
中的第一个参数。以相同的方式被加载到DataSet
中,以相同的方式将DataSet
加载到ArrayList<IBarDataSet>
中,但是由于某种原因一个起作用,而另一个则不起作用。有人知道这个问题是什么吗?这是MPAndroidChart
的显式BarEntry
的错误吗?
答案 0 :(得分:0)
我找到了解决方法。首先,我必须创建一个在onCreate()
中调用的初始化方法:
private Map<String, Map<String, Float>> assessmentData = new HashMap<>();
private void initAssessmentData() {
for(int i = 0; i < assessmentKeys.size(); i++) {
final Map<String, Float> categoryNameScore = new HashMap<>();
mAssessmentCategoryRefs.get(i).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for(DataSnapshot postSnapShot : dataSnapshot.getChildren()) {
Category category = postSnapShot.getValue(Category.class);
categoryNameScore.put(category.getName(), (float) category.getCategoryScore());
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
assessmentData.put(assessmentKeys.get(i), categoryNameScore);
}
}
然后将数据放入图中,我只需要将代码更改为此:
final ArrayList<BarDataSet> dataSets = new ArrayList<>();
ArrayList<IBarDataSet> allDataSets = new ArrayList<>();
final BarData data = new BarData(allDataSets);
for(int j = 0; j < assessmentKeys.size(); j++ ) {
final int jTracker = j;
final ArrayList<BarEntry> entries = new ArrayList<>();
dataSets.add(j, new BarDataSet(entries, assessmentName.get(j)));
Log.d("Received_Data", "Getting data for " + assessmentName.get(j));
for(String key : assessmentData.keySet()) {
if(key.equals(assessmentKeys.get(j))) {
Map<String, Float> categoryData = assessmentData.get(key);
for(String key2 : categoryData.keySet()) {
if(categoryNames.contains(key2)) {
entries.add(new BarEntry(categoryNames.indexOf(key2), categoryData.get(key2)));
}
}
}
}
Random random = new Random();
int randomR = random.nextInt(256);
int randomG = random.nextInt(256);
int randomB = random.nextInt(256);
dataSets.get(j).setColor(Color.rgb(randomR, randomG, randomB));
allDataSets.add(dataSets.get(j));
data.notifyDataChanged();
mBarChart.notifyDataSetChanged();
mBarChart.invalidate();