MPAndroidChart: Creating a closed chart (circular line chart)

跟風遠走 提交于 2019-12-12 18:26:42

问题


I need to draw a "closed chart" in my Android app, like this:

The xIndex of the data first increases then decreases. Like in this example:

[3,3],[4,4],[5,5],[6,4],[7,3],[6,2],[5,1],[4,2],[3,3]

When I try drawing a LineСhart with this data in MPAndroidChart, it only renders the first half of data (prior to the fall of the xIndex). The other data is not shown.

How can I draw this data correctly with MPAndroidChart ?


回答1:


The sample app on the Google Play Store gives an example of every kind of chart available in the library. Likewise, the source code is available for you to inspect and see if it has the feature you want.

Additionally, the wiki specifically says that unordered line chart entries are not supported.

Please be aware that this library does not officially support drawing LineChart data from an Entry list not sorted by the x-position of the entries in ascending manner.

That being said, if you are willing to pre-process your data you should be able to achieve what you want. You would have to take your data and extract two distinct DataSets to which you would apply the same styling. I was able to achieve something like the effect you want using this technique:

Here is the code:

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.Menu;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.TextView;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.Legend.LegendForm;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;

import java.util.ArrayList;
import java.util.Random;

public class LineChartActivity4 extends DemoBase {

    private LineChart mChart;
    private Random rand;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        rand = new Random();
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_linechart);

        mChart = (LineChart) findViewById(R.id.chart1);
        mChart.setDrawGridBackground(false);
        mChart.getDescription().setEnabled(false);
        mChart.setTouchEnabled(true);
        mChart.setScaleXEnabled(true);
        mChart.setScaleYEnabled(true);
        mChart.setPinchZoom(true);
        mChart.getLegend().setEnabled(false);
        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.removeAllLimitLines(); // reset all limit lines to avoid overlapping lines
        leftAxis.enableGridDashedLine(10f, 10f, 0f);
        leftAxis.setDrawZeroLine(false);
        leftAxis.setDrawLimitLinesBehindData(true);
        mChart.getAxisRight().setEnabled(true);
        mChart.setDragOffsetX(20);
        mChart.setData(generateClosedData(90, 180, 15));
        mChart.animateX(2500);
    }

    private LineData generateClosedData(float offset, float range, float delta) {
        ArrayList<Entry> topEntries = new ArrayList<>();
        ArrayList<Entry> bottomEntries = new ArrayList<>();

        for (int x = 0; x <= 180; x++) {
            float val1 = offset + generateValue(x, range, delta);
            float val2 = offset - generateValue(x, range, delta);
            topEntries.add(new Entry(x, val1));
            bottomEntries.add(new Entry(x, val2));
        }

        LineDataSet set1 = generateLineDataSet(topEntries);
        LineDataSet set2 = generateLineDataSet(bottomEntries);

        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        dataSets.add(set1);
        dataSets.add(set2);
        LineData data = new LineData(dataSets);
        return data;
    }

    private float generateValue(int x, float range, float delta) {
        float sine = (float) Math.sin(Math.toRadians(x));
        float scaledSine = sine * range;
        if (x == 0 || x == 180) {
            return scaledSine;
        }
        else {
            return scaledSine + rand.nextFloat() * delta;
        }
    }

    @NonNull
    private LineDataSet generateLineDataSet(ArrayList<Entry> topEntries) {
        LineDataSet set;
        set = new LineDataSet(topEntries, "");
        set.setColor(Color.BLUE);
        set.setDrawCircles(false);
        set.setLineWidth(4f);
        set.setValueTextSize(9f);
        set.setFormSize(15.f);
        return set;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.line, menu);
        return true;
    }
}


来源:https://stackoverflow.com/questions/40532564/mpandroidchart-creating-a-closed-chart-circular-line-chart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!