异步添加到 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);

因为 RadarEntryBarEntryBarDataSetRadarDataSetIBarDataSetIRadarDataSet 都共享父级 类在它们之间,我假设我能够以与 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 也会遇到同样的问题。据我所知,RadarEntryBarEntry 之间唯一真正的区别是索引是 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();