异步添加到 DataSet 时 BarEntry 和 RadarEntry 之间的区别
Difference between BarEntry and RadarEntry when added to a DataSet asynchronously
我正在处理两个不同的图表,一个是雷达图,它比较 "assessment" 中所有 "categories" 的分数与另一个 "assessments",还有一个分组条形图允许用户在 "assessment" 中 select "categories" 并将它们与其他 "assessments" 进行比较。数据是从 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();
数据未绘制成图表,尽管我的日志显示它正确地跳过了与 selected 名称不匹配的类别,如果匹配则添加该类别的分数。
这是什么原因?起初我认为这可能是由于从 firebase 中提取的数据的异步性质,但如果是这样,我的 RadarChart 也会遇到同样的问题。据我所知,RadarEntry
和 BarEntry
之间唯一真正的区别是索引是 RadarEntry
中的第二个参数,但 BarEntry
中的第一个参数。条目以相同的方式加载到 DataSet
中,DataSet
以相同的方式加载到 ArrayList<IBarDataSet>
中,但出于某种原因,一个有效,另一个无效。有谁知道问题是什么?这是 MPAndroidChart
的显式 BarEntry
的错误吗?
我找到了解决方法。首先,我必须创建一个在 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();
我正在处理两个不同的图表,一个是雷达图,它比较 "assessment" 中所有 "categories" 的分数与另一个 "assessments",还有一个分组条形图允许用户在 "assessment" 中 select "categories" 并将它们与其他 "assessments" 进行比较。数据是从 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
的错误吗?
我找到了解决方法。首先,我必须创建一个在 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();