I'm having a problem with MPAndroidChart. I have a RecyclerView with the LineChart inside a CardView as an item. The recyclerView is inside a fragment. The first time I show the fragment the line chart is not drawing correctly in the first time showing. And I tried to remove and show the fragment again. The line width and circle radius in the first show are like half sized compare to the second and many times after. And sometimes the circles in the first showing are not drew at all. And it's only happen when the application is start from the beginning. The chart is very basic with less properties, so I cannot find out the reason.

The image first time showing

The image second time showing

The line chart view xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="240dp"
    android:layout_margin="8dp"
    app:cardCornerRadius="5dp">

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/line_chart"
        android:layout_margin="8dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    </android.support.v7.widget.CardView>

The function to initialize the chart line data:

public void initChartData() {
    this.lineDataSet = new LineDataSet(entries, title);
    lineDataSet.setDrawCircles(true);
    lineDataSet.setColor(Color.RED);
    lineDataSet.setCircleColor(Color.RED);
    lineDataSet.setDrawIcons(false);

    // line thickness and point size
    lineDataSet.setCircleRadius(2f);
    lineDataSet.setLineWidth(1f);

    // draw points as solid circles
    lineDataSet.setDrawCircleHole(false);

    // customize legend entry
    lineDataSet.setFormLineWidth(1f);
    //lineDataSet.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
    lineDataSet.setFormSize(15.f);
    lineDataSet.setValueTextSize(9f);
    lineDataSet.setDrawValues(false);

    ArrayList<ILineDataSet> dataSets = new ArrayList<>();
    dataSets.add(lineDataSet);
    this.data = new LineData(dataSets);
}

The chart ViewHolder:

public ChartItemViewHolder(@NonNull View itemView) {
    super(itemView);
    this.view = itemView;
    lineChart = view.findViewById(R.id.line_chart);
    lineChart.clearAllViewportJobs();
    lineChart.clear();
    lineChart.setBackgroundColor(Color.WHITE);
    lineChart.getDescription().setEnabled(false);
    lineChart.setTouchEnabled(true);
    lineChart.setDrawGridBackground(false);
    lineChart.setDragEnabled(true);
    lineChart.setScaleEnabled(true);
    lineChart.setPinchZoom(false);
    lineChart.getAxisRight().setEnabled(false);
    lineChart.setExtraBottomOffset(8);

    Legend l = lineChart.getLegend();
    l.setForm(Legend.LegendForm.LINE);
}

The Adapter:

 @Override
public void onBindViewHolder(@NonNull final ChartItemViewHolder chartItemViewHolder, int i) {
    chartItemViewHolder.item = itemList.get(i);
    chartItemViewHolder.lineChart.getXAxis().setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return CommonUtils.toTimeString((long) value+chartItemViewHolder.item.getRefTimeStamp());
        }
    });
    chartItemViewHolder.lineChart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(context, "CLICKED", Toast.LENGTH_SHORT).show();
        }
    });
    chartItemViewHolder.lineChart.clear();
    chartItemViewHolder.lineChart.setData(chartItemViewHolder.item.getLineData());
}
Answer

Make sure to call

Utils.init(context)

at least once before setting line width.

For example in your application's onCreate() method.

The setLineWidth method needs to have device's metrics. It uses Utils class for this purpose, but if it is not initialized it returns your value without applying conversion.

An error is actually logged when this happens:

E/MPChartLib-Utils: Utils NOT INITIALIZED. You need to call Utils.init(...) at least once before calling Utils.convertDpToPixel(...). Otherwise conversion does not take place.

  • 1
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions