MPAndroidChart:创建一个闭合的图表(圆形折线图) [英] MPAndroidChart: Creating a closed chart (circular line chart)

查看:218
本文介绍了MPAndroidChart:创建一个闭合的图表(圆形折线图)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

数据的xIndex首先增加,然后减少.像本例一样:

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

当我尝试在MPAndroidChart中用此数据绘制Linehart时,它仅呈现数据的前半部分(在xIndex下降之前).其他数据未显示.

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

解决方案

源代码,以查看其是否具有所需的功能. /p>

此外, Wiki 特别指出,无序折线图条目不是支持的.

请注意,该库并不正式支持未按条目的x位置升序排列的条目列表中的绘制LineChart数据.

话虽如此,如果您愿意对数据进行预处理,那么您应该能够实现所需的功能.您将必须获取数据并提取两个不同的数据集,然后将它们应用相同的样式.使用这种技术,我能够达到您想要的效果:

这是代码:

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

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 ?

解决方案

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

这篇关于MPAndroidChart:创建一个闭合的图表(圆形折线图)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆