[BUG] Combined chart BarData.getDataSetCount() null pointer exception
I have Combined chart which builds in 2 different ways (Line chart or Candle + Line + Bar chart). On first load both ways works fine (init app with 1st way or 2nd - ok).
If i draw 2nd group of charts and then try to draw first Line chart - i'm getting NPE: java.lang.NullPointerException: Attempt to invoke virtual method 'int com.github.mikephil.charting.data.BarData.getDataSetCount()' on a null object reference
on that line of code: mCombinedChart.setData(combinedData);
I think i need to clear chart somehow or it is bug?
my code: private void buildChart(ArrayList<GraphPoint> graphData, final CoinExchangeData coin) { mCombinedChart.clear();
//axis
YAxis yAxisRight = mCombinedChart.getAxisRight();
yAxisRight.setSpaceBottom(220f);
yAxisRight.setEnabled(true);
yAxisRight.setTextColor(getResources().getColor(R.color.landscape_chart_text_active));
YAxis yAxisLeft = mCombinedChart.getAxisLeft();
yAxisLeft.setEnabled(false);
XAxis xAxis = mCombinedChart.getXAxis();
xAxis.setEnabled(false);
xAxis.setTextColor(getResources().getColor(R.color.landscape_chart_text_active));
xAxis.setValueFormatter(new XAxisValueFormatter(graphData));
mCombinedChart.setTouchEnabled(true);
mCombinedChart.setHighlightPerDragEnabled(true);
mCombinedChart.setHighlightPerTapEnabled(true);
mCombinedChart.getDescription().setEnabled(false);
mCombinedChart.setScaleEnabled(false);
mCombinedChart.setDoubleTapToZoomEnabled(false);
mCombinedChart.setNoDataText(App.getContext().getResources().getString(R.string.graph_no_data));
//Line chart
if (App.getPreferencesInstance().getInt(PreferencesManager.LANDSCAPE_CHART_MODE_KEY, PreferencesManager.LANDSCAPE_CHART_MODE_LINE) == PreferencesManager.LANDSCAPE_CHART_MODE_LINE) {
mCombinedChart.getLegend().setEnabled(false);
Legend legend = mCombinedChart.getLegend();
legend.setEnabled(true);
legend.setTextColor(getResources().getColor(R.color.landscape_chart_legend));
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
List<Entry> values = new ArrayList<>();
for (int i = GRAPH_OFFSET; i < graphData.size(); ++i) {
values.add(new Entry((float) i, graphData.get(i).high.floatValue()));
}
LineDataSet lineDataSet = new LineDataSet(values, coin.symbol);
lineDataSet.setDrawValues(false);
lineDataSet.setDrawCircles(false);
lineDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
chartMin = lineDataSet.getYMin();
chartMax = lineDataSet.getYMax();
mCombinedChart.getAxisRight().setAxisMinimum(chartMin);
mCombinedChart.getAxisRight().setAxisMaximum(chartMax);
lineDataSet.setDrawFilled(true);
lineDataSet.setFillDrawable(LandscapeChartActivity.this.getResources().getDrawable(R.drawable.gradient_landscape_chart));
lineDataSet.setColor(LandscapeChartActivity.this.getResources().getColor(R.color.landscape_chart_gold));
lineDataSet.setLineWidth(2.0f);
LineData lineData = new LineData(lineDataSet);
if (lineData.getEntryCount() == 0) {
showChartReload();
return;
}
CombinedData combinedData = new CombinedData();
combinedData.setData(lineData);
mCombinedChart.setData(combinedData);
} else { // Candle chart
List<CandleEntry> valuesRateData = new ArrayList<>();
List<BarEntry> valuesVolumeData = new ArrayList<>();
for (int i = GRAPH_OFFSET; i < graphData.size(); ++i) {
GraphPoint graphPoint = graphData.get(i);
valuesRateData.add(new CandleEntry((float) i - GRAPH_OFFSET, graphPoint.high.floatValue(), graphPoint.low.floatValue(),
graphPoint.open.floatValue(), graphPoint.close.floatValue()));
valuesVolumeData.add(new BarEntry((float) i - GRAPH_OFFSET, graphPoint.volume.floatValue()));
}
CandleDataSet candleDataSet = new CandleDataSet(valuesRateData, coin.fullName.concat(" (").concat(coin.symbol).concat(")"));
candleDataSet.setDrawValues(false);
BarDataSet barDataSet = new BarDataSet(valuesVolumeData, getResources().getString(R.string.volume));
barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
barDataSet.setColor(getResources().getColor(R.color.landscape_chart_volumes_bars));
//chart.getXAxis().setTextColor(getResources().getColor(R.color.graph_axis));
//chart.getAxisRight().setTextColor(getResources().getColor(R.color.graph_axis));
yAxisLeft.setSpaceTop(400f);
yAxisLeft.setEnabled(false);
yAxisRight.setSpaceBottom(20f);
candleDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
//candleDataSet.setDrawFilled(true);
candleDataSet.setIncreasingColor(getResources().getColor(R.color.landscape_chart_green));
candleDataSet.setDecreasingColor(getResources().getColor(R.color.landscape_chart_red));
candleDataSet.setNeutralColor(getResources().getColor(R.color.landscape_chart_candle_shadow));
candleDataSet.setShadowColor(getResources().getColor(R.color.landscape_chart_candle_shadow));
candleDataSet.setIncreasingPaintStyle(Paint.Style.FILL);
candleDataSet.setShadowWidth(0.66f);
candleDataSet.setHighLightColor(getResources().getColor(R.color.landscape_chart_gold));
CandleData candleData = new CandleData(candleDataSet);
CombinedData combinedData = new CombinedData();
combinedData.setData(candleData);
BarData barData = new BarData(barDataSet);
combinedData.setData(barData);
if (App.getPreferencesInstance().getInt(PreferencesManager.LANDSCAPE_INDICATOR_KEY, PreferencesManager.LANDSCAPE_INDICATOR_WMA7) == PreferencesManager.LANDSCAPE_INDICATOR_WMA7) {
ArrayList<PointXY> points = Indicators.evaluateIndicatorWMA7(graphData);
List<Entry> valuesWMA7Data = new ArrayList<>();
for (int i = 0; i < points.size(); ++i) {
valuesWMA7Data.add(new Entry(points.get(i).x.floatValue(), points.get(i).y.floatValue()));
}
LineDataSet indicatorWMA7DataSet = new LineDataSet(valuesWMA7Data, "WMA7");
indicatorWMA7DataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
indicatorWMA7DataSet.setColor(getResources().getColor(R.color.landscape_chart_indicator));
indicatorWMA7DataSet.setDrawCircles(false);
indicatorWMA7DataSet.setLineWidth(1.2f);
LineData lineDataWMA7 = new LineData(indicatorWMA7DataSet);
combinedData.setData(lineDataWMA7);
}
mCombinedChart.setData(combinedData);
}
showChart(coin);
}
Found source code, where that bug happens:
in CombinedChartRenderer
@Override public void initBuffers() {
for (DataRenderer renderer : mRenderers)
renderer.initBuffers();
}
When redrawing Line chart after drawing 3 charts it calls initBuffers with previous values (Line, Bar and Candle)
I met the same problem, A bad solution: combinedData.setData(barData()); before combinedData.setData(otherData);
I have same problem. My solution : chart.setData(null); chart.setData(newData);
I have same problem. My solution : chart.setData(null); chart.setData(newData);
Great Bro. It fix the problem!!
CombinedData data = new CombinedData();
switch(data) { // Only for BarChart case BarChart LineData ld = new LineData(); ld.clearValues(); chartData.setData(ld); chartData.setData(barData); break;
// Only for LineChart case LineChart BarData bd = new BarData(); bd.clearValues(); chartData.setData(bd); chartData.setData(lineData); break;
// Both the Chart (Line & Bar Chart) case BothChart chartData.setData(lineData); chartData.setData(barData); }
I have same problem. My solution : chart.setData(null); chart.setData(newData);
also work for me