MPAndroidChart:创建一个封闭的图表(圆形折线图)

时间:2016-11-10 16:30:51

标签: android mpandroidchart

我需要在我的Android应用中绘制一个“封闭图表”,如下所示:

a line chart that forms a rough circle

数据的xIndex首先增加然后减少。就像在这个例子中一样:

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

当我尝试在MPAndroidChart中使用此数据绘制LineСhart时,它只渲染前半部分数据(在xIndex下降之前)。其他数据未显示。

如何使用MPAndroidChart正确绘制此数据?

1 个答案:

答案 0 :(得分:1)

sample app on the Google Play Store给出了库中可用的各种图表的示例。同样,source code可供您检查并查看它是否具有您想要的功能。

此外,the wiki明确指出不支持无序折线图条目。

  

请注意,此库不正式支持从条目列表中绘制LineChart数据,而不是按条目的x位置按升序排序。

话虽如此,如果您愿意预处理数据,您应该能够达到您想要的效果。您必须获取数据并提取两个不同的DataSet,您将应用相同的样式。我能够使用这种技术实现你想要的效果:

a "closed chart" in blue

以下是代码:

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;
    }
}